0

This question is related to this thread How to add a Line between two moving Objects with Python?

But the answer in this thread uses an edge, while I want it to be a cylinder (just like a bond connecting two atoms).

How do I extend from that answer to achieve this? Thank you.

1 Answers1

0

enter image description here

All you need to change in the previous answer so that it would generate cylinder connectors instead of boxes, is setting the Skin modifier to smooth shading, and adding a subdivision surface modifier on top of it.

import bpy, bmesh
C = bpy.context

# Reference two cylinder objects
c1 = bpy.data.objects['C1']
c2 = bpy.data.objects['C2']

# Create new connector mesh and mesh object and link to scene
m = bpy.data.meshes.new('connector')

bm = bmesh.new()
v1 = bm.verts.new( c1.location )
v2 = bm.verts.new( c2.location )
e  = bm.edges.new([v1,v2])

bm.to_mesh(m)

o = bpy.data.objects.new( 'connector', m )
C.scene.collection.objects.link( o )

# Hook connector vertices to respective cylinders
for i, cyl in enumerate([ c1, c2 ]):
    bpy.ops.object.select_all( action = 'DESELECT' )
    cyl.select_set(True)
    o.select_set(True)
    C.view_layer.objects.active = o # Set connector as active

    # Select vertex
    bpy.ops.object.mode_set(mode='OBJECT')
    o.data.vertices[i].select = True    
    bpy.ops.object.mode_set(mode='EDIT')

    bpy.ops.object.hook_add_selob() # Hook to cylinder

    bpy.ops.object.mode_set(mode='OBJECT')
    o.data.vertices[i].select = False 

m = o.modifiers.new('Skin', 'SKIN')

## New bit starts here
m.use_smooth_shade = True

m = o.modifiers.new('Subsurf', 'SUBSURF' )
m.levels = 2
m.render_levels = 2

## End of new bit
bpy.ops.object.select_all( action = 'DESELECT' )
TLousky
  • 16,043
  • 1
  • 40
  • 72
  • Thanks so much the answer. I have a few questions. Why do I need to set both level and render_levels to 2? And, are there any resources related to this that you'd like to recommend? Blender Python resources seem so scattered for me and involve only very basic stuff. I'm pretty familiar with Python and I don't want to deal with the GUI Blender. – Mick Krongchon Apr 16 '19 at 20:03
  • Also, how do I customize the bond (color, diameter)? – Mick Krongchon Apr 16 '19 at 20:19
  • In my experience, the best way to learn blender scripting is to understand the app and its capabilities in depth. You can use tooltips to figure out how to script manual actions, then read the documentation and answers here in Stack to find more efficient ways to do stuff than simple automation of manual actions (but first it's always best to simply get things to work). There are also nice scripting courses in CG Cookie and lots of blogs and resources if you look for 'em. – TLousky Apr 16 '19 at 20:43
  • To change the color you need to apply a material to the bond object, then change it properties (see answers related to this topic here in Stack). To change the diameter you need to change the skin_vertices radius as shown here: https://blender.stackexchange.com/a/1593/15861 – TLousky Apr 16 '19 at 20:46
  • After rendering, z-fighting occurs. I wonder which part of the above code causes the overlapping faces that led to z-fighting. This is the related question: https://blender.stackexchange.com/questions/140607/the-material-looks-bad-after-rendered – Mick Krongchon May 15 '19 at 15:29
  • My only problem with this answer is that the subsurf modifier is "making the bond shorter". What I would like is a way (in blender 2.8) to obtain the "licorice" representation, where both atoms and bonds have the same radius. -> https://i.imgur.com/iDeuLEk.png . In short, I would like a way to script a full cylinder (not rounded at the extremities) which is connected to two atoms (spheres). – Alessio Valentini Oct 16 '19 at 09:51