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)