3
$\begingroup$

I'd like to use blender to animate motion of nodes in a graph (~50000 nodes) that I've exported from gephi (different layouts of the same graph). Let's call them spheres to avoid confusing them with Blender's material/compositing nodes. Similarly, instead of graph edges, let's call them connections.

I'm pretty sure the best way to handle the spheres is with duplivert, but I'm having trouble with the connections.

I'm trying things out on a small graph before I scale up. Here I have bezier curves set up for the connections, getting the appropriate curvature by scaling the handles. Looks fine for a static image, but will quickly break down when the spheres start moving.

enter image description here

The first thing to do is hook the curve ends to the spheres. This way, the curves move around when the spheres do. The problem now is getting the handles rotated and scaled based on the new sphere positions:

enter image description here

Is there a way to get the connections' curve handles to be pointed in the right direction, and scaled to give appropriate curvature, based on the position of the speheres?

$\endgroup$
  • 1
    $\begingroup$ I'd just be careful using the term 'nodes' as nodes are already a technical term in blender for materials and compositing. $\endgroup$ – Ray Mairlot Dec 22 '14 at 15:32
  • 1
    $\begingroup$ The thing that question is missing for me is getting the curvature of the connections right. It's fine to hook the ends of the curves to the spheres, but I can't think of a good way to point the handles in the right direction, or have them scaled correctly. $\endgroup$ – ajwood Dec 22 '14 at 15:43
  • $\begingroup$ @RayMairlot As ajwood explained, that question is not really a duplicate. $\endgroup$ – PGmath Dec 23 '14 at 3:39
1
$\begingroup$

Assumption: If your graph has approx 50k junctions, I will assume you will import/generate such graph with python in blender.

If I were you, I would do all the animating also with python. If you do that, you also don't need to set all the hooks with python (yay!).

  • When you'll be building the graph, store junctions and connections into some list. You should use some nice classes for them and remember inside them what belongs to what and also remember data paths to each connection ends and handles vertices.

  • Then you create a function that will receive such list via a global variable and that will edit all junction positions and connections vertices and handles according to current frame. The function only takes 1 parameter - the scene.

    def update_fce(scene):
        # get data
        global list
    
        # get frame
        frame = scene.frame_current
    
        # here move stuff to where it is supposed to be at frame
        return
    
  • The last step is to add this function into frame change callback list so it is called everytime the frame is changed:

    bpy.app.handlers.frame_change_pre.append(update_fce)
    
$\endgroup$
  • $\begingroup$ He said he will be importing the data, not generating with a script. $\endgroup$ – PGmath Dec 23 '14 at 3:40
  • $\begingroup$ Ok I added import/generate. It doesnt matter though it looks like a custom scripts job anyways. $\endgroup$ – Jaroslav Jerryno Novotny Dec 23 '14 at 8:46
  • $\begingroup$ I'll definitely have to write a custom script to get the graph into blender (I'll try to make it generic to accept a .gephi file). Still not too sure how to work out the math though. $\endgroup$ – ajwood Dec 24 '14 at 1:42
0
$\begingroup$
  1. I am unsure on the details of this part of your question. "getting the appropriate curvature by scaling the handles." What defines the appropriate curvature. Why aren't the connections just line segments between spheres?

  2. Here is the best answer I can give, until I understand more about #1. A code snippet from a different thread on BA regarding handle scaling. Once I understand exactly how you are trying to scale the handles, adapting this should not be difficult. This example should have all the neceessary mechanics to accomplish what you want whether by setting automatic handles, or by scaling them manually once you calculate a new location for them.

    def main(context):
        #Find the Blender object of interest 
        crv_obj = context.object
        #Get access to the curve object data
        crv_data = crv_obj.data
        #active spline
        spline = crv_data.splines.active
        #Find the active bezier control point bcp
        selected_points = [bcp for bcp in spline.bezier_points if bcp.select_control_point]
    
        for bez_point in selected_points:
            #Find the active control point location
            b_loc = bez_point.co
    
            #Find the left handle location
            l_loc = bez_point.handle_left
    
            #Find the right handle location
            r_loc = bez_point.handle_right
    
            #Claculate length handle right
            l_len = (l_loc - b_loc).length
    
            #Calculate length handle left
            r_len = (r_loc - b_loc).length
    
            #Set automatic
            bez_point.handle_right_type = 'AUTO'
            bez_point.handle_left_type = 'AUTO'
    
            #Now set handle type to aligned
            bez_point.handle_right_type = 'ALIGNED'
            bez_point.handle_left_type = 'ALIGNED'
    
            #Reset left handle to correct length
            l_loc_new = bez_point.handle_left
            l_vec = l_loc_new - b_loc
            bez_point.handle_left = b_loc + l_len * l_vec.normalized()
    
            #Reset right handle to correct length
            r_loc_new = bez_point.handle_right
            r_vec = r_loc_new - b_loc
            bez_point.handle_right = b_loc + r_len * r_vec.normalized()
    
$\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.