mesh translation speed through python

I’m writing a script which center the mesh of my object and rotates it 45 degrees. In basis I’m repositioning the pivot. I can do this almost realtime by hand but using python it takes 47seconds. Is there a faster way to this then I’m currently doing?

import Blender
from Blender import sys, Mathutils, Object, Mesh
from Blender.Mathutils import *

def bct_tanslatevector(OB):
    #Get boundingbox and calculate translate vector to center
    BB= OB.getBoundBox()
    print("Calculation start coord: ",BB[0])
    NEWPOS=Vector(-0.5*(BB[4][0]-BB[0][0]), -0.5*(BB[7][1]-BB[4][1]), BB[0][2] )
    print("Calculation target coord: ",NEWPOS)
    TRANSVEC=NEWPOS-BB[0]
    print("Calculation translation vector: ",TRANSVEC)
    return(TRANSVEC)

def main():
    test=Blender.Object.GetSelected()[0]
    
    #only needed if object is not already pos 0
    test.setLocation(Vector(0,0,0))
    Blender.Redraw()
    
    #Create a translationmatrix
    TRANSMAT= TranslationMatrix(bct_tanslatevector(test))

    #Create a 45degree rotation matrix
    ROTMAT= RotationMatrix(45,4,'z')
    
    #Combine the 2 matrices so we only need to calculate once
    #tricky but should work, damn doesn't
    #need a mesh update first before rotation
    #TRANSMAT[0]=ROTMAT[0]
    #TRANSMAT[1]=ROTMAT[1]
    
    t = sys.time()
    ME=test.getData()
    ME.transform(TRANSMAT)
    ME.update()
    ME.transform(ROTMAT)
    ME.update()
    print 'Mesh Processing done in %.6f sec.' % (sys.time()-t)
    

    
if __name__ == '__main__':
    main()

but how about this?

It’s just a quick hack using a slightly modified starting script for Object Editing.
(TextEditor, File->ScriptTemplates->ObjectEditing

from Blender import Window, sys 
import bpy
import Blender


M_PI = 3.1415926
Deg2Rad = M_PI / 180.0
 
 
def myTransRotateSelectedObjects(sce, distX, angleX): 
    # Move & rotate context objects on the x axis 
    for ob in sce.objects.context: 
        ob.LocX += distX 
        ob.RotX += Deg2Rad * angleX

 
def main(): 
    # Gets the current scene, there can be many scenes in 1 blend file. 
    sce = bpy.data.scenes.active 
     
    Window.WaitCursor(1) 
    t = sys.time() 
     
    # Run the object editing function 
    myTransRotateSelectedObjects(sce, 1.0, 45.0) 
     
    # Timing the script is a good way to be aware on any speed hits when scripting 
    print 'My Script finished in %.2f seconds' % (sys.time()-t) 
    Window.WaitCursor(0) 
    Blender.Redraw() 
     
main() 


I suppose you’d just want to change the code so that it took in a vector for the translation, and I guess another for the 3 rotation values.
Only changes the values used for display - trans and rot(doesn’t manipulate the vertex data itself afaik), runs in 0.00 secs for both cubes and 100,000 + vert objects.The time it takes to redraw the screen is the time it takes to do its work.

S.

But this is script is modifying the object in world space. I need to modify the mesh in it’s own coordinate system. I’m basically changing the pivot point of the object.

In the Mesh class you can’t just set LocX and RotX. You can only translate through it’s matrix AFAIK.

I’m currently looking into running the code in Window.EditMode(1)
But need to read first :slight_smile:

Oops, guess I missed that in your first post.

So, have you got many of things you need to do this to, or does it need to be completely automated?

Cos if you run my script then hit Ctrl-A (Scale & Rotation to ObData), there’s still a whole bunch of time left.

I just did it on a 24,578 vertex (sub divided cube) with your script and it took 29 seconds.
I used my script then hit Ctrl-A and it took less than 1.5 seconds.

Perhaps there’s a way to “Apply Scale & Rotation to ObData” using python. Ideasman42 would know.

Yes I need to automate a lot of objects and time is indeed of big importance. It’s used for a autnomomous system so no manual intervention. The weird thing is is that is sometimes very fast and sometimes not. I currently testing different codes and I have processing time from 0.4sec to 47sec.

The sad thing is I need to do 3 operations on the mesh. First I need to reset the matrix since the original is not very usable. Then I need to rotate the mesh 45 degrees and finally translate to the object center.

I just restarted Blender again and I now just went from 47sec to 0.8sec. I also noticed issuing a Blender.Redraw() helps me getting my calculations right. Without it my mesh just ends somewhere in space.

Mesh re-orientation done in 73.438072 sec.
Saved session recovery to /home/arnaud/.blender/quit.blend

Blender quit
arnaud@naudilus:~/Documents/z25/bodycount/tests/BlenderExporter$
arnaud@naudilus:~/Documents/z25/bodycount/tests/BlenderExporter$
arnaud@naudilus:~/Documents/z25/bodycount/tests/BlenderExporter$ blender
guessing ‘blender-bin’ == ‘/usr/bin/blender-bin’
Compiled with Python version 2.5.1.
Checking for installed Python… got it!

Mesh re-orientation done in 0.719310 sec.

import Blender
from Blender import sys, Mathutils, Object, Mesh, Window
from Blender.Mathutils import *

def bct_tanslatevector(OB):
    #Get boundingbox and calculate translate vector to center
    BB= OB.getBoundBox()
    print("Calculation start coord: ",BB[0])
    NEWPOS=Vector(-0.5*(BB[4][0]-BB[0][0]), -0.5*(BB[7][1]-BB[4][1]), BB[0][2] )
    print("Calculation target coord: ",NEWPOS)
    TRANSVEC=NEWPOS-BB[0]
    print("Calculation translation vector: ",TRANSVEC)
    return(TRANSVEC)

def bct_resetorientation(OB):
    #if Vector(0,0,0) != Vector(OB.getLocation()):
    #    print "reset position"
    #    OB.setLocation(Vector(0,0,0))    
    #    Blender.Redraw()
        
    t = sys.time()
    ME=OB.getData()
    
    #First reset the current Matrix to a normal one
    print(OB.getMatrix())    
    ME.transform(OB.getMatrix())
    ME.update()    
    Blender.Redraw()
    MAT=Blender.Mathutils.Matrix(
                 [1.0,0.0,0.0,0.0],
                 [0.0,1.0,0.0,0.0],
                 [0.0,0.0,1.0,0.0],
                 [0.0,0.0,0.0,1.0]) 
    OB.setMatrix(MAT)
    print(OB.getMatrix())
    #Create a translationmatrix
    MAT= TranslationMatrix(bct_tanslatevector(OB))
    ME.transform(MAT)
    ME.update()
    Blender.Redraw()
    
    #Create a -45degree rotation matrix
    MAT= RotationMatrix(-45,4,'z')
    ME.transform(MAT)
    ME.update()
    Blender.Redraw()
    
    print 'Mesh re-orientation done in %.6f sec.' % (sys.time()-t)
    

def main():
    bct_resetorientation(Blender.Object.GetSelected()[0])
    

    
if __name__ == '__main__':
    main()

Here we go again. This is from Blender which is running a while already

Mesh re-orientation done in 71.491295 sec.

Now I restart blender:

Mesh re-orientation done in 1.039816 sec.

My automation involves restarting Blender for every object :slight_smile: But still this is weird.
I’ll try an undo and restart the script.

Mesh re-orientation done in 1.034620 sec.

Hmmm weird. Well, time to eat :cool: