0
$\begingroup$

I have a mixture of polygonal chains, quite dense. These chains represent mixture of polymers (~5000 chains). I want to render it photorealistic (without using VMD or similar special software) so they look like smooth curves. Chains are stored, for now, just as sequence of coordinates of the vertices. Is there a format which supports such data so I can import chains into blender? Or shall I convert every chain into concatenated cylinders? Do you know some tools which do it with smoothing the chain with splines?

$\endgroup$
  • 2
    $\begingroup$ What format are those chains in? If it's something custom you will have to write your own importer. $\endgroup$ – Jaroslav Jerryno Novotny Jan 27 '16 at 12:10
  • $\begingroup$ I can write a converter to any standard open format, yet I don't know one which supports just lines (without polygons) $\endgroup$ – Kirill Lykov Jan 27 '16 at 16:39
1
$\begingroup$

You might just want to use python to convert the coordinates into a mesh. There are many examples on the internet. I'll include an excerpt from http://web.purplefrog.com/~thoth/blender/python-cookbook/triangle-donut.html because it has an accompanying narrative linked at the top:

import bpy
import math


def triangleDonut(name, nChunks, r1, r2, z1, z2):
    verts=[]
    faces = []
    for i in range(2*nChunks):
        # the first ring of vertices; we create them later in the loop
        v1=i*3
        v2 = v1+1
        v3 = v1+2
        # the second ring of vertices; these refer to vertices created next time
        v4 = v1+3
        v5 = v1+4
        v6 = v1+5
        if (i+1 >= 2*nChunks): # connect the end to the start
           v4=0
           v5=1
           v6=2
        # each ring is at a different angle from the center, eventually sweeping a full circle by the end of the loop
        theta = i*math.pi/nChunks
        if 0 == i%2:
            z=z1
        else:
            z=z2
        # basic triangle geometry here
        c = math.cos(theta)
        s = math.sin(theta)
        # append the coordinates for v1..v3 to the verts list
        verts.append( [r1*c, r1*s, 0] )
        verts.append( [r2*c, r2*s, z] )
        verts.append( [r2*c, r2*s, -z] )
        # build faces that go from the freshly added vertices to the vertices we will add in the next loop
        faces.append( [v1, v4, v5, v2] )
        faces.append( [v2, v5, v6, v3] )
        faces.append( [v3, v6, v4, v1] )

    mesh = bpy.data.meshes.new(name);
    mesh.from_pydata(verts, [], faces)
    mesh.validate(True)
    mesh.show_normal_face = True

    obj = bpy.data.objects.new(name, mesh)
    scn = bpy.context.scene
    scn.objects.link(obj)



triangleDonut("donut", 20, 3, 2, 1,1.5)

There are many other examples at that site and around the internet. the from_pydata method is probably a good search term, although it comes up with startlingly few results on stackexchange

$\endgroup$
1
$\begingroup$

If these vertices are just points on a curve, you could use python to fabricate a Bezier curve. I'll include an excerpt from http://web.purplefrog.com/~thoth/blender/python-cookbook/create-bezier.html

import bpy

name = "wiggle"

curve = bpy.data.curves.new(name, 'CURVE')

curve.dimensions = '3D'
# only if you need some non-zero Z coordinates

spline = curve.splines.new('BEZIER')
# options are 'POLY', 'BEZIER', 'BSPLINE', 'CARDINAL', 'NURBS'

# the spline starts off with a single point, we want one more.
spline.bezier_points.add(1)
b0 = spline.bezier_points[0]
b1 = spline.bezier_points[1]

b0.handle_left = (-2.5, -0.5, 0)
b0.co = (-2, 0, 0)
b0.handle_right = (-1, 1, 0)

b1.handle_left = (1, -1, 0)
b1.co = (2, 0, 0)
b1.handle_right = (2.5, 0.5, 0)


# curves data can have multiple unconnected curves

s2 = curve.splines.new('BEZIER')

# we want 3 = 1+2
s2.bezier_points.add(2)

b0 = s2.bezier_points[0]
b1 = s2.bezier_points[1]
b2 = s2.bezier_points[2]

b0.handle_left = (-0.5, 2.5, 1)
b0.co = (0, 2, 1)
b0.handle_right = (1, 1, 1)
b1.handle_left = (1, 1, 1)
b1.co = (0, 0, 1)
b1.handle_right = (-1, -1, 1)
b2.handle_left = (-1, -1, 1)
b2.co = (0, -2, 1)
b2.handle_right = (0.5, -2.5, 1)

#

s3 = curve.splines.new('BEZIER')

s3.bezier_points.add(1)
b0 = s3.bezier_points[0]
b1 = s3.bezier_points[1]

b0.handle_left = (-1, 1, -1)
b0.co = (0, 1, -1)
b0.handle_right = (1, 1, -1)

b1.handle_left = (1, -1, -1)
b1.co = (0, -1, -1)
b1.handle_right = (-1, -1, -1)

s3.use_cyclic_u = True
# forms a closed loop

#
#

ob = bpy.data.objects.new(name, curve)

scn = bpy.context.scene
scn.objects.link(ob)
ob.select = True

for i in range(len(curve.splines)):
    spline = curve.splines[i]
    print("spline[%d]" % i)
    for j in range(len(spline.bezier_points)):
        bp = spline.bezier_points[j]
        print("bp[%d] = %s(%s , %s , %s)%s" % (j, bp.handle_left_type, bp.handle_left, bp.co, bp.handle_right, bp.handle_right_type))

Of course, that just gives you the central curve. You'll probably want to add a "Bevel Object", probably using a second bezier circle object as the bevel.

If you want them to be straight cylinders, go with a POLY instead of a BEZIER. If you do go with BEZIER, you'll have to figure out exactly what you want to do with the control points/handles (I'm partial to bp[i].co +- 0.3*(bp[i-1].co-bp[i+1].co) )

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.