Hello everyone,

I currently work on a python script, which involves a kind of self-made array modifier. It creates a mesh along a path, whose coordinates are stored in an array named “Coordinates”. The coordinates of the object, which is supposed to be repeated along this path, are stored in an array named “CrossSection”.

My script is working absolutely fine for me in terms of actual results. But it takes my computer about 20 minutes to create the mesh of a path with 2500 points and a cross-section with 16 points. Additionally to that, the calculation time does not increase linear at all. 1000 points of the same cross-section would only take two minutes. If you run my script, you’ll see the non-linear progress in the system console.

Since I am not a professional programmer at all, this is the first time I ever had to wonder about the performance of my script. I already did everything I could, but my knowledge is quite restricted, so I hoped such a high-skill-level-community could maybe give me a hint or two of how to improve my efficiency here.

Thanks to everyone in advance, who even reads my script

```
#The following script is not performance critical.
#But the ciritical part needs it to work in Blender.
#So skip reading this part for now.
#You will only need it, if you want to test the script in Blender.
import bpy
import os.path
import bmesh
import math
import numpy as np
Coordinates = {}
CrossSection = {}
TotalRows = 1000
TotalPoints = 10
CoordRows = np.zeros((3,1))
CoordPoints = np.zeros((3,1))
CoordRes = np.zeros((3,1))
RotX = np.zeros((3,3))
RotY = np.zeros((3,3))
RotZ = np.zeros((3,3))
RotZX = np.zeros((3,3))
RotRes = np.zeros((3,3))
RotX[0,0] = 1
RotY[1,1] = 1
RotZ[2,2] = 1
for RowNo in range(0,TotalRows):
Coordinates[RowNo,0] = RowNo
Coordinates[RowNo,1] = 0
Coordinates[RowNo,2] = 0
Coordinates[RowNo,3] = 0
Coordinates[RowNo,4] = 0
Coordinates[RowNo,5] = 0
for PointNo in range(0,TotalPoints):
CrossSection[PointNo,0] = 0
CrossSection[PointNo,1] = PointNo-round(TotalPoints/2)
CrossSection[PointNo,2] = 0
ObjMesh = bpy.data.meshes.new("Mesh")
Obj = bpy.data.objects.new("Object", ObjMesh)
bpy.context.scene.objects.link(Obj)
bpy.context.scene.objects.active = Obj
#So now the interesting stuff...
#This is the performance-critical part:
for RowNo in range(0,TotalRows): #loop through every row in the coordinates array
AngleX = Coordinates[RowNo,3]*math.pi/180 #some variable readouts from the coordinates array
AngleY = Coordinates[RowNo,4]*math.pi/180
AngleZ = Coordinates[RowNo,5]*math.pi/180
RotX[1,1] = math.cos(AngleX) #definition of rotation matrices
RotX[1,2] = (-1)*math.sin(AngleX)
RotX[2,2] = math.cos(AngleX)
RotX[2,1] = math.sin(AngleX)
RotY[0,0] = math.cos(AngleY)
RotY[0,2] = math.sin(AngleY)
RotY[2,0] = (-1)*math.sin(AngleY)
RotY[2,2] = math.cos(AngleY)
RotZ[0,0] = math.cos(AngleZ)
RotZ[0,1] = (-1)*math.sin(AngleZ)
RotZ[1,0] = math.sin(AngleZ)
RotZ[1,1] = math.cos(AngleZ)
RotZX = np.dot(RotZ,RotX) #generating resulting rotation matrix
RotRes = np.dot(RotZX,RotY)
for PointNo in range(0,TotalPoints): #loop through every point of the cross-section
PreviousVertex = (RowNo-1)*TotalPoints+PointNo #defining vertices, that will be used for new faces
CurrentVertex = RowNo*TotalPoints+PointNo
bm = bmesh.new() #prepares blender for new mesh coming up
bm.from_mesh(Obj.data)
for Dimension in range(0,3): #read out the coordinates of current row
CoordRows[Dimension,0] = Coordinates[RowNo,Dimension]
CoordPoints[Dimension,0] = CrossSection[PointNo,Dimension]
CoordPoints[0] = 0 #otherwise this slot would content absolute nonsense. A cross sections does not content x-coordinates
CoordPoints[1,0] = CoordPoints[1,0]
CoordRes = CoordRows+np.dot(RotRes,CoordPoints) #calculates coordinates in context with the rotation matrix
bm.verts.new((CoordRes[0,0], CoordRes[1,0], CoordRes[2,0])) #creates new vertex
bm.to_mesh(Obj.data) #assings new vertex to object
bm.free() #dunno myself why I have to put this here...
if (PointNo > 0) and (RowNo > 0): #to create new faces you need an existing row already
bpy.context.tool_settings.mesh_select_mode=[True,False,False] #I want to select vertices next
if (((RowNo/2) - int(RowNo/2)) == ((PointNo/2) - int(PointNo/2))): #I want neighboring triangle pairs to have different orientation. Dont't ask...
bm = bmesh.new() #again new mesh (this time for the faces instead of the vertices)
bm.from_mesh(Obj.data)
bm.verts.ensure_lookup_table() #I received an error message telling me to put this line here
bm.faces.new([bm.verts[PreviousVertex-1], bm.verts[PreviousVertex],bm.verts[CurrentVertex-1]]) #Creates my two triangles connected to the new vertex
bm.faces.new([bm.verts[CurrentVertex-1], bm.verts[PreviousVertex],bm.verts[CurrentVertex]])
bm.to_mesh(Obj.data) #assings new faces to object
bm.free()
else: #simply the same as above, but the different orientation of the faces
bm = bmesh.new()
bm.from_mesh(Obj.data)
bm.verts.ensure_lookup_table()
bm.faces.new([bm.verts[CurrentVertex-1], bm.verts[PreviousVertex-1],bm.verts[CurrentVertex]])
bm.faces.new([bm.verts[PreviousVertex-1], bm.verts[PreviousVertex],bm.verts[CurrentVertex]])
bm.to_mesh(Obj.data)
bm.free()
print(str(RowNo) + ' of ' + str(TotalRows)) # your progress output in the system console, Sir!
```