Vertex global coordinates?


(RipSting) #1

I’m looking for a simple way of finding the global position of a vertex. Using the object matrix sucks. Does anyone know an alternate way of returning the actual position, even if the mesh is a child of another object?


(theeth) #2

use the object’s matrix. It’s fast enough if you use a function.

Martin


(RipSting) #3

Ok I found a mat2euler function in Eeshlo’s lightflow exporter but…

Loc and size are perfect, but I’m not sure how to use the rot data. Let me explain:

After I’ve generated all the fibers of hair/grass- I copy the rotation, location, and size of the base mesh to the newly created fiber mesh. However, if the base mesh was rotated at all it rotates the fiber mesh. A sample problem from that scenario would be grass that grows “up” along the X axis instead of the Z axis.

So I’m trying to apply those transformations WHILE I’m creating verticies. I’m attempting to rotate the points around the object’s center (which it sees as (0,0,0)) and should be pretty simple, but it’s proving difficult to find out exactly what I need to do to accomplish this. I’ve already searched the forums, but I haven’t found the answer.

I’ll try searching the net for a mathematical solution, but if you have the answer, feel free to post it!


(jms) #4

Just multiply the position of vertex [ME] by the matrix of the Object [OB].


#M=Matrix
#v=vertex
 
def multmat(M,v):
      x=v.co[0];  y=v.co[1]; z=v.co[2]
      x1 = (x * M[0][0]) + (y * M[1][0]) + (z * M[2][0]) + M[3][0]
      y1 = (x * M[0][1]) + (y * M[1][1]) + (z * M[2][1]) + M[3][1]
      z1 = (x * M[0][2]) + (y * M[1][2]) + (z * M[2][2]) + M[3][2]

      v.co[0]=x1; v.co[1]=y1; v.co[2]=z1
      return  v
 


(RipSting) #5

Holy @#[email protected]!!! Thats EASY!!!

import Blender
from Blender import Object, NMesh

objName = "Circle"


#M=Matrix 
#v=vertex 

def multmat(M,v): 
      x=v.co[0];  y=v.co[1]; z=v.co[2] 
      x1 = (x * M[0][0]) + (y * M[1][0]) + (z * M[2][0]) + M[3][0] 
      y1 = (x * M[0][1]) + (y * M[1][1]) + (z * M[2][1]) + M[3][1] 
      z1 = (x * M[0][2]) + (y * M[1][2]) + (z * M[2][2]) + M[3][2] 

      v.co[0]=x1; v.co[1]=y1; v.co[2]=z1 
      return  v 


obj = Object.Get ("Circle")
me = obj.data
mat = obj.matrix
new = NMesh.GetRaw()

for v in me.verts:
	new.verts.append(multmat(mat,v))

NMesh.PutRaw(new,"fixed")

(RipSting) #6

I modified the multmat function so that it could run on faces. But I have a question: How would I only multiply the rotation and size, and leave the location alone? I’d like for my new meshes to share the same centers as the base meshes.

The matrix math is still pretty confusing to me. :-?

And there seems to be a problem: Normals are not recalculated! I tried creating a new NMesh.Face and appending the vertex coordinates to it, but it won’t recalculate the normals until after I exit edit mode!
The equation to calculate normals is :

N = ( P2 - P1 ) x ( P3 - P2 )

Where N is the normal vector, and P are the vertices. But how do I find the cross product in python? It doesn’t allow direct cross multiplication of arrays or whatever you call them… I don’t know how you’d calculate the normal of a triangle, either:(


(jms) #7

Try this:


import Blender 
from Blender import Object, NMesh 

objName = "Circle" 
#M=Matrix 
#v=vertex 

def multmat(M,v): 
       x=v.co[0];  y=v.co[1]; z=v.co[2] 
       x1 = (x * M[0][0]) + (y * M[1][0]) + (z * M[2][0]) + M[3][0] 
       y1 = (x * M[0][1]) + (y * M[1][1]) + (z * M[2][1]) + M[3][1] 
       z1 = (x * M[0][2]) + (y * M[1][2]) + (z * M[2][2]) + M[3][2] 
       v.co[0]=x1; v.co[1]=y1; v.co[2]=z1 
       return  v 

def resetcenterfirst(Obj,v):
      for n in range(3):
            v.co[n]-=obj.loc[n]
      return v

obj = Object.Get ("Circle") 
me = obj.data 
mat = obj.matrix 
new = NMesh.GetRaw() 

for v in me.verts: 
    new.verts.append(multmat(mat,v)) 
    new.verts[len(new.verts)-1]=resetcenterfirst(obj, new.verts[len(new.verts)-1])

Newobj=NMesh.PutRaw(new,"fixed")
Newobj.loc=obj.loc


jm


(theeth) #8

we have a vector/matrix math library we are using for Dynamica and some other scripts (like Eeshlo’s LF export). If you want it, I could e-mail it to you.

Martin


(jms) #9

Try this:


import Blender 
from Blender import Object, NMesh 

objName = "Circle" 
#M=Matrix 
#v=vertex 
...


jm[/quote]

Hey, it’s like to do a Ctrl-a with Alt-p
:slight_smile:


(eeshlo) #10

If you omit the ‘+M[3][x]’ part, you don’t have to reset the location, since M[3] is the location of the object.


(RipSting) #11

Ok so great I figured out the +M[3][X] part last night while I was messing around with it. But still having major problems with calculating the normals. :x

I don’t understand why you have to assign the normals on the vertex. There’s no such thing as a vertex normal, only a face normal. A vertex normal is only supposed to be the average of the surrounding face normals. So I’m not trying to write a simple function to return the normal vector of three vertices that are passed to it.

Here’s a .zip containing a blend with a few scripts related to normals. The one I’ll end up using is “DrawNormals”:
http://www.fireengine51.org/blender/translation.zip

Some links with information I’ve tried to follow
http://www-2.cs.cmu.edu/afs/cs/academic/class/15462/web.97f/notes/geomod.pdf
http://www.cs.unc.edu/~hoff/techrep/pntnorm.html


(RipSting) #12

Really really need help with this. This is the last thing before I can release my fiber generator! Normals are the key to its soul!


(eeshlo) #13

def vecsub(a,b):
	return [a[0]-b[0], a[1]-b[1], a[2]-b[2]]

def renormal(p1,p2,p3):
	#returns the face normal
	norm = [0,0,0]
	v1 = vecsub(p1, p2)
	v2 = vecsub(p1, p3)
	norm[0] = v1[1]*v2[2] - v1[2]*v2[1]
	norm[1] = v1[2]*v2[0] - v1[0]*v2[2]
	norm[2] = v1[0]*v2[1] - v1[1]*v2[0]	
	return norm


(RipSting) #14

DAMNIT EESHLO!!! YOU’RE A GOD!