Hello everybody,
I have written a script (see below) that places duplicates of an object on every face of an other object (I made it to create objects in “The Matrix”-style, i.e. with Matrix-symbols on the surfaces). Luckily it does what I want it to do, but if my objects have altogether more than 3000 faces the script runs so slowly that I could wait years for another 1000 copies… The first copies are made very quickly but the time per copy increases more and more for later copies.
Any ideas why my script slows down and how I can improve it?
Thanks for help,
Lukas
import Blender
from Blender import Mesh
from Blender.Mesh import *
import math
from math import *
from random import randint
Sphere = Blender.Object.Get(“Sphere”)
MeshS = Mesh.Get(“Sphere”)
n = 0
i = len(MeshS.faces)
for n in range(i): # on every face a copy of the Object “Zeichen” shall be placed
Zeichen = Blender.Object.Get(“Zeichen”)
Fn = MeshS.faces[n] # current face
SMat = Sphere.matrix
Xn = Fn.cent[0] * SMat[0][0] + Fn.cent[1] * SMat[1][0] + Fn.cent[2] * SMat[2][0] + SMat[3][0]
Yn = Fn.cent[0] * SMat[0][1] + Fn.cent[1] * SMat[1][1] + Fn.cent[2] * SMat[2][1] + SMat[3][1]
Zn = Fn.cent[0] * SMat[0][2] + Fn.cent[1] * SMat[1][2] + Fn.cent[2] * SMat[2][2] + SMat[3][2]
for ob in Blender.Object.GetSelected():
ob.sel = 0
Zeichen.sel = 1
Blender.Object.Duplicate()
Duplikat = Blender.Object.Get("Zeichen"+".001")
Duplikat.sel = 0
Zeichen.setLocation(Xn,Yn,Zn)
no = Fn.no # to get the orientation right (winkel=angle)
if (no[0] > 0):
if (no[1] >= 0):
winkelxy = math.atan(no[1]/no[0])
if (no[1] < 0):
winkelxy = 2*math.pi-math.atan(-no[1]/no[0])
if (no[0] == 0):
if (no[1] >= 0):
winkelxy = math.pi/2
if (no[1] < 0):
winkelxy = 3*math.pi/2
if (no[0] < 0):
if (no[1] >= 0):
winkelxy = math.pi-math.atan(no[1]/-no[0])
if (no[1] < 0):
winkelxy = math.pi+math.atan(no[1]/no[0])
winkelxyz = -math.pi/2+math.acos(no[2])
x = 0
y = winkelxyz
z = winkelxy
Zeichen.setEuler([x,y,z])
Zeichen.sel = 0
Zeichen.setName("Duplikat")
Duplikat.setName("Zeichen"+str(r))
hi LPSN,
the same problem here. It depends of blenders intern object management by creating new objects into scene. No easy solution found till now. I wish the issue will be focused after 2.50 release.
LPSN, your code with some modifications here:
the issue was the usage of Duplicate() method. Replaced now with objects.new().
get_Euler() could be replaced too, with API matrix method.
It creates 10.000 Duplicates in ca.30sek. although slowing down to 1.10sek pro 100 Duplicates at the end.
Will be nice if you public your finished script here.
migius
import Blender
from Blender import Mesh
from Blender.Mesh import *
import math
from math import *
from random import randint
print '
----------START ---------'
#---------------------------------
def get_Euler(no):
if (no[0] > 0):
if (no[1] >= 0):
winkelxy = math.atan(no[1]/no[0])
if (no[1] < 0):
winkelxy = 2*math.pi-math.atan(-no[1]/no[0])
if (no[0] == 0):
if (no[1] >= 0):
winkelxy = math.pi/2
if (no[1] < 0):
winkelxy = 3*math.pi/2
if (no[0] < 0):
if (no[1] >= 0):
winkelxy = math.pi-math.atan(no[1]/-no[0])
if (no[1] < 0):
winkelxy = math.pi+math.atan(no[1]/no[0])
winkelxyz = -math.pi/2+math.acos(no[2])
x = 0
y = winkelxyz
z = winkelxy
return x,y,z
#--MAIN-------------------------------------
scn = Blender.Scene.GetCurrent()
Sphere = Blender.Object.Get("Sphere")
MeshS = Mesh.Get("Sphere")
ii, li = 0, 0
time0 = Blender.sys.time() #time marker0
scn.objects.selected = []
SMat = Sphere.matrix
Zeichen = Blender.Object.Get("Zeichen")
for Fn in MeshS.faces: # on every face a copy of the Object "Zeichen" shall be placed
Xn = Fn.cent[0] * SMat[0][0] + Fn.cent[1] * SMat[1][0] + Fn.cent[2] * SMat[2][0] + SMat[3][0]
Yn = Fn.cent[0] * SMat[0][1] + Fn.cent[1] * SMat[1][1] + Fn.cent[2] * SMat[2][1] + SMat[3][1]
Zn = Fn.cent[0] * SMat[0][2] + Fn.cent[1] * SMat[1][2] + Fn.cent[2] * SMat[2][2] + SMat[3][2]
Duplikat = scn.objects.new(Zeichen.data, "Duplikat")
Duplikat.loc = [Xn,Yn,Zn]
x,y,z = get_Euler(Fn.no) # to get the orientation right (winkel=angle)
Duplikat.setEuler([x,y,z])
ii += 1
if ii>100:
ii = 0
li += 1
time1 = Blender.sys.time()
print 'deb: %i 100-step finished in %.4f sec.'% (li, (time1-time0))
time0 = time1
print '---------The END--------