2

How can I insert a value in a array of vectors using Python 3.x?

The full code is below. It is using Blender 2.82a:

import bpy
import mathutils
import math

ob = bpy.context.object

#1) Get all vertexes and place in vector array
vec = [v.co for v in ob.data.vertices]

print("vec=%s" % vec)

It creates an array of Vectors of x,y,z values:

vec=[Vector((1.0, 1.0, 1.0)), Vector((1.0, 1.0, -1.0)), Vector((1.0, -1.0, 1.0)), Vector((1.0, -1.0, -1.0)), Vector((-1.0, 1.0, 1.0)), Vector((-1.0, 1.0, -1.0)), Vector((-1.0, -1.0, 1.0)), Vector((-1.0, -1.0, -1.0))]

And I would like to insert a 7 at the start of each vector so it would look like:

vec=[Vector((7, 1.0, 1.0, 1.0)), Vector((7, 1.0, 1.0, -1.0)), Vector((7, 1.0, -1.0, 1.0)), Vector((7, 1.0, -1.0, -1.0)), Vector((7, -1.0, 1.0, 1.0)), Vector((7, -1.0, 1.0, -1.0)), Vector((7, -1.0, -1.0, 1.0)), Vector((7, -1.0, -1.0, -1.0))]

The .insert doesn't seem to work in vectors.

Added animated gif of what it creates

Rick T
  • 4,391
  • 1
  • 20
  • 64

2 Answers2

2

By default Vertices vectors are in 3 dimensions so we need to create a new one with 4 dimensions.

import bpy
from mathutils import Vector

try:
    vectors = [Vector((7.0, v.co.x, v.co.y, v.co.z)) for v in bpy.context.object.data.vertices]    
    print(vectors)
except AttributeError:
    print('Please select a mesh object')

Result :

enter image description here

Gorgious
  • 30,723
  • 2
  • 44
  • 101
2

Using numpy

Can do this quickly using foreach_get in conjunction with numpy. Speedup will be noticeably quicker for high vertex count meshes.

import bpy
import numpy as np

context = bpy.context
# assume that object is a ob.type == 'MESH'
ob = context.object
me = ob.data


coords = np.empty(len(me.vertices) * 3) # ravelled list
me.vertices.foreach_get("co", coords) # load in coords

coords4d = np.insert(
        np.reshape(coords, (-1, 3)), # reshaped to 3d
        0, # insert before index 0
        values=7, # insert values
        axis=1) # insert a column

Result on default cube

>>> coords4d
array([[ 7.        ,  1.        ,  0.99999994, -1.        ],
       [ 7.        ,  1.        , -1.        , -1.        ],
       [ 7.        , -1.00000012, -0.99999982, -1.        ],
       [ 7.        , -0.99999964,  1.00000036, -1.        ],
       [ 7.        ,  1.00000048,  0.99999946,  1.        ],
       [ 7.        ,  0.99999934, -1.0000006 ,  1.        ],
       [ 7.        , -1.00000036, -0.99999964,  1.        ],
       [ 7.        , -0.99999994,  1.        ,  1.        ]])

Mapping result to a list of vectors

>>> list(map(Vector, coords4d))
[Vector((7.0, 1.0, 0.9999999403953552, -1.0)), Vector((7.0, 1.0, -1.0, -1.0)), Vector((7.0, -1.0000001192092896, -0.9999998211860657, -1.0)), Vector((7.0, -0.9999996423721313, 1.0000003576278687, -1.0)), Vector((7.0, 1.0000004768371582, 0.999999463558197, 1.0)), Vector((7.0, 0.9999993443489075, -1.0000005960464478, 1.0)), Vector((7.0, -1.0000003576278687, -0.9999996423721313, 1.0)), Vector((7.0, -0.9999999403953552, 1.0, 1.0))]

Or similarly with quaternions (as per example)

>>> for q in map(Quaternion, coords4d):
...     q
...     
Quaternion((7.0, 1.0, 0.9999999403953552, -1.0))
Quaternion((7.0, 1.0, -1.0, -1.0))
Quaternion((7.0, -1.0000001192092896, -0.9999998211860657, -1.0))
Quaternion((7.0, -0.9999996423721313, 1.0000003576278687, -1.0))
Quaternion((7.0, 1.0000004768371582, 0.999999463558197, 1.0))
Quaternion((7.0, 0.9999993443489075, -1.0000005960464478, 1.0))
Quaternion((7.0, -1.0000003576278687, -0.9999996423721313, 1.0))
Quaternion((7.0, -0.9999999403953552, 1.0, 1.0))

Related:

Having the coords as a numpy array can do matrix math on list vectors quickly see:

Replace matrix @ vector list comprehensions with something more efficient

Note: re accepted answer, Going to revisit Best practices: Use try except sparingly Rather than checking an object is not a mesh by catching an attribute error can simply check for it

ob = context.object
if ob and ob.type == 'MESH':
     ...
else:
    print("Select a mesh")

IMO use try / except as a last resort. For example a typo like vetrices will pass thru and tell you to select a mesh.. making scripts a nightmare to debug.

batFINGER
  • 84,216
  • 10
  • 108
  • 233