1

In a sense I have "solved" my original problem but I don't understand why/how its solved.

I have a script that generates a number of objects and then attempts to create straight lines via a Nurbs path, adapted from the question/answer here. Using Hooks is important because I want the 'lines' between objects to persist in relative terms to their parents.

The solution I've found is that if I create an otherwise unused empty object with defined coordinates (uncomment out line 52 bpy.ops.object.empty_add(location=list(objA.location),)) everything works as expected. If I remove this hack-ish work around though, the coordinates for the ends of the nurbs paths are all translated/scaled which is not the desired behavior.

I thought the "answer" might be related to object vs world space (and maybe it still is?) or maybe a misunderstanding of context, but this hail-Mary work around of mine worked so thought I'd quit while I was ahead/ask a more specific question: "why does this 'hack' work?" and perhaps "is there a better way?"

Code example showing the undesirable behavior (uncomment out line 52 to see correct behavior)

#names and locations used to drive example
pointDict ={'obj_0': (3.453742273151139, 0.5159551844564874,0.0),
            'obj_1': (12.792816730076403, -16.205364756872424,0.0),
            'obj_2': (14.709455272016719, -11.60690199900985,0.0),
            'obj_3': (8.69197652556564, -13.612261105632582,0.0),
            'obj_4': (9.52728618428947, 2.4890328748868917,0.0)}

import bpy C = bpy.context from itertools import combinations

#template cube to clone, used for minimum viable example bpy.ops.mesh.primitive_cube_add(size=0.5, align='WORLD', location=(10.0,10.0,0.0), scale=(1, 1, 1))

baseCube = bpy.data.objects['Cube'] #known/assumed name

#clone base object with predetermined coordiantes for keyName in pointDict: xVar, yVar, zVar = pointDict[keyName] objClone = baseCube.copy() objClone.name = keyName objClone.location.x = xVar objClone.location.y = yVar objClone.location.z = zVar C.collection.objects.link(objClone)

#create pair-wise line combinations between cubes #and hook to cubes to maintain position/connections when moved at later point

moddified from https://blender.stackexchange.com/questions/194400/adding-a-hook-to-a-nurbs-path-with-python

pCounter = 0 for pair in combinations(list(pointDict.keys()),2): pCounter=+1

objA = bpy.data.objects[pair[0]]
objB = bpy.data.objects[pair[1]]

path = bpy.data.curves.new('_path_{}'.format(pCounter), 'CURVE')
path.dimensions = "3D"
path.bevel_depth=0.05

spline = path.splines.new(type='NURBS')
spline.points.add(1)
spline.use_endpoint_u = True
spline.use_endpoint_v = True
path_ob = bpy.data.objects.new('_Path_new_{}'.format(pCounter), path)


spline.points[0].co = (list(objA.location)+[1.0])

#not sure why adding this helps, but it fixes things??  uncoment following line to see "good" results
#bpy.ops.object.empty_add(location=list(objA.location),)
hm1 = path_ob.modifiers.new(name=f"Hook_A",type='HOOK',)
hm1.object = objA
hm1.vertex_indices_set([0]) 
#'Hook' first vertex of spline/path
spline.points[1].co = (list(objB.location)+[1.0])
hm2 = path_ob.modifiers.new(name=f"Hook_B",type='HOOK',)
hm2.object = objB
hm2.vertex_indices_set([1])

C.collection.objects.link(path_ob)


Richard W
  • 113
  • 3

1 Answers1

3

Force an update.

Using the add empty object operator (or any operator) has the side effect of forcing a view_layer update. In version < 2.8 this was a scene.update().

It can be the case in a script execution that object matrices are not yet updated when their values are being queried.

Updating the viewlayer in the same loop as the operator produces the same result as with operator, without operator. (circa line 30)

pCounter = 0
for pair in combinations(list(pointDict.keys()),2):
    pCounter = +1 # Did  you mean += 1
    bpy.context.view_layer.update()  # <== UPDATE
    objA = bpy.data.objects[pair[0]]
batFINGER
  • 84,216
  • 10
  • 108
  • 233
  • @brockmann ... lol see there is method in my madness https://blender.stackexchange.com/questions/194400/adding-a-hook-to-a-nurbs-path-with-python#comment332807_198756 – batFINGER Mar 08 '21 at 20:09