Community
Maya Programming
Welcome to Autodesk’s Maya Forums. Share your knowledge, ask questions, and explore popular Maya SDK topics.
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

polyNormalPerVertex normals issue?

29 REPLIES 29
SOLVED
Reply
Message 1 of 30
Anonymous
6588 Views, 29 Replies

polyNormalPerVertex normals issue?

Anonymous
Not applicable

I'm trying to get and set a vertex normal using the `polyNormalPerVertex` function, when I select a vertex and set it using: 

cmds.polyNormalPerVertex( xyz=(0.5,0,0))  


`x` normals should be set to 0.5. 

 

But when I go to query it I get back 3 values for x and can't seem to understand what they represent, and how I can get back my initial value I set to vertex. 

 

print( cmds.polyNormalPerVertex( query=True, x=True ))
[1.0, 1.0, 1.0]

And a little more confusing, when I query the xyz normals I get:

print( cmds.polyNormalPerVertex( query=True, xyz=True ))
[1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0]

I'm assuming it's a collapsed tuple, `x1y1z1 x2y2z2 x3y3z3`?

 

All I'm looking to do is transfer one vertex normals to another vertex on another object, so I'd like to be able to get the normals and just pass them to a setter, and don't see this being the proper way, or am I missing something?

0 Likes

polyNormalPerVertex normals issue?

I'm trying to get and set a vertex normal using the `polyNormalPerVertex` function, when I select a vertex and set it using: 

cmds.polyNormalPerVertex( xyz=(0.5,0,0))  


`x` normals should be set to 0.5. 

 

But when I go to query it I get back 3 values for x and can't seem to understand what they represent, and how I can get back my initial value I set to vertex. 

 

print( cmds.polyNormalPerVertex( query=True, x=True ))
[1.0, 1.0, 1.0]

And a little more confusing, when I query the xyz normals I get:

print( cmds.polyNormalPerVertex( query=True, xyz=True ))
[1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0]

I'm assuming it's a collapsed tuple, `x1y1z1 x2y2z2 x3y3z3`?

 

All I'm looking to do is transfer one vertex normals to another vertex on another object, so I'd like to be able to get the normals and just pass them to a setter, and don't see this being the proper way, or am I missing something?

29 REPLIES 29
Message 2 of 30
mcw0
in reply to: Anonymous

mcw0
Advisor
Advisor

"However, when queried, the command returns all normals (all vtx-face combinations) on the vertex, regardless of whether they ar shared or not."

 

That's from the documentation.  So I'm assuming you are getting 3 sets of 3 values is because the selected vertex is common to 3 faces.

"However, when queried, the command returns all normals (all vtx-face combinations) on the vertex, regardless of whether they ar shared or not."

 

That's from the documentation.  So I'm assuming you are getting 3 sets of 3 values is because the selected vertex is common to 3 faces.

Message 3 of 30
Anonymous
in reply to: mcw0

Anonymous
Not applicable
Thanks for the reply.

Though, I read the docs as well, I still don't understand that seeing how
when I set up x to 0.5 it's still 1. How does that work?

So is there anyway I can get these normals so I can copy them to another
normal with this library? Or any other quick way? I feel like I'm going
down the wrong path.
0 Likes

Thanks for the reply.

Though, I read the docs as well, I still don't understand that seeing how
when I set up x to 0.5 it's still 1. How does that work?

So is there anyway I can get these normals so I can copy them to another
normal with this library? Or any other quick way? I feel like I'm going
down the wrong path.
Message 4 of 30
jmreinhart
in reply to: Anonymous

jmreinhart
Advisor
Advisor

So when you run

cmds.polyNormalPerVertex( xyz=(0.5,0,0))  

It sets the normal to that vector; but, it normalize it first. so (.5,0,0) becomes (1,0,0) so the vector has a length of 1.0.

 

When you query the normals for a vertex using the cmds command you get a vector for each vertex-face pairing. To turn that into a single normal vector would require a weighted average of the vectors (and I don't know of a way in cmds to get those weights.

 

There is an API command that will get average normal vector of the vertex automatically.

https://stackoverflow.com/questions/42075004/maya-api-vs-python-commands-vertex-normals

So when you run

cmds.polyNormalPerVertex( xyz=(0.5,0,0))  

It sets the normal to that vector; but, it normalize it first. so (.5,0,0) becomes (1,0,0) so the vector has a length of 1.0.

 

When you query the normals for a vertex using the cmds command you get a vector for each vertex-face pairing. To turn that into a single normal vector would require a weighted average of the vectors (and I don't know of a way in cmds to get those weights.

 

There is an API command that will get average normal vector of the vertex automatically.

https://stackoverflow.com/questions/42075004/maya-api-vs-python-commands-vertex-normals

Message 5 of 30
mcw0
in reply to: Anonymous

mcw0
Advisor
Advisor

Ah yes, as pointed out, normals in Maya are always normalized.  I forgot to mention that.  As for what you want to do, now that you know why Maya is returning so many values, you just need to average them.  And then apply the average to your goal vertex.  You can try "polyAverageNormal".  Or you can just add up the values and divide knowing that the values are x, y, z, x, y, z.....

Ah yes, as pointed out, normals in Maya are always normalized.  I forgot to mention that.  As for what you want to do, now that you know why Maya is returning so many values, you just need to average them.  And then apply the average to your goal vertex.  You can try "polyAverageNormal".  Or you can just add up the values and divide knowing that the values are x, y, z, x, y, z.....

Message 6 of 30
Anonymous
in reply to: jmreinhart

Anonymous
Not applicable

Thanks for your replies, I did think it was normalizing but didn't fully see the API handling that, doesn't make sense that the setter for the normals is different for the getter in the query, counter intuitive to me. 

 

So I have an issue...

 

print(cmds.polyNormalPerVertex( query=True, x=True))
[1.0, 1.0, 1.0]

print(cmds.polyNormalPerVertex( query=True, xyz=True))
[1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0]

 

 

x is 1 in this case, but when I go to apply the code below: 

 

Screenshot_7.png

 

import maya.api.OpenMaya as om
import maya.cmds as cmds

selectionList = om.MSelectionList()
selectionList.add('pCube1')
dagPath = selectionList.getDagPath(0)
mesh = om.MFnMesh(dagPath)

cmds.select( 'pCubeShape2.vtx[3]', r=True )
cmds.polyNormalPerVertex( xyz=(mesh.getVertexNormal(3, False, space=om.MSpace.kWorld))) 

#print(mesh.getVertexNormal(3, False, space=om.MSpace.kWorld))
#(0.57735, 0.57735, 0.57735)

 

 

It grabs the weighted normals, but it's off for my case, it keeps returning 0.57 when it should be 1. 

 

What am I doing wrong? 

 

 

0 Likes

Thanks for your replies, I did think it was normalizing but didn't fully see the API handling that, doesn't make sense that the setter for the normals is different for the getter in the query, counter intuitive to me. 

 

So I have an issue...

 

print(cmds.polyNormalPerVertex( query=True, x=True))
[1.0, 1.0, 1.0]

print(cmds.polyNormalPerVertex( query=True, xyz=True))
[1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0]

 

 

x is 1 in this case, but when I go to apply the code below: 

 

Screenshot_7.png

 

import maya.api.OpenMaya as om
import maya.cmds as cmds

selectionList = om.MSelectionList()
selectionList.add('pCube1')
dagPath = selectionList.getDagPath(0)
mesh = om.MFnMesh(dagPath)

cmds.select( 'pCubeShape2.vtx[3]', r=True )
cmds.polyNormalPerVertex( xyz=(mesh.getVertexNormal(3, False, space=om.MSpace.kWorld))) 

#print(mesh.getVertexNormal(3, False, space=om.MSpace.kWorld))
#(0.57735, 0.57735, 0.57735)

 

 

It grabs the weighted normals, but it's off for my case, it keeps returning 0.57 when it should be 1. 

 

What am I doing wrong? 

 

 

Message 7 of 30
Anonymous
in reply to: Anonymous

Anonymous
Not applicable

Event tried: 

import maya.api.OpenMaya as om
import maya.cmds as cmds

#on pCube1
cmds.polyNormalPerVertex( xyz=(0.5,0,0))  

selectionList = om.MSelectionList()
selectionList.add('pCube1')
dagPath = selectionList.getDagPath(0)
mesh = om.MFnMesh(dagPath)

vert = mesh.getNormals()

for v in vert:
    print(v)
(0, 0, 1)
(0, 0, 1)
(1, 0, 0)
(0, 0, 1)
(0, 1, 0)
(1, 0, 0)
(0, 1, 0)
(0, 1, 0)
(0, 0, -1)
(0, 0, -1)
(0, 0, -1)
(0, 0, -1)
(0, -1, 0)
(0, -1, 0)
(0, -1, 0)
(0, -1, 0)
(1, 0, 0)
(1, 0, 0)
(1, 0, 0)
(1, 0, 0)
(-1, 0, 0)
(-1, 0, 0)
(-1, 0, 0)
(-1, 0, 0)

And not getting the 0.5 I should be...

0 Likes

Event tried: 

import maya.api.OpenMaya as om
import maya.cmds as cmds

#on pCube1
cmds.polyNormalPerVertex( xyz=(0.5,0,0))  

selectionList = om.MSelectionList()
selectionList.add('pCube1')
dagPath = selectionList.getDagPath(0)
mesh = om.MFnMesh(dagPath)

vert = mesh.getNormals()

for v in vert:
    print(v)
(0, 0, 1)
(0, 0, 1)
(1, 0, 0)
(0, 0, 1)
(0, 1, 0)
(1, 0, 0)
(0, 1, 0)
(0, 1, 0)
(0, 0, -1)
(0, 0, -1)
(0, 0, -1)
(0, 0, -1)
(0, -1, 0)
(0, -1, 0)
(0, -1, 0)
(0, -1, 0)
(1, 0, 0)
(1, 0, 0)
(1, 0, 0)
(1, 0, 0)
(-1, 0, 0)
(-1, 0, 0)
(-1, 0, 0)
(-1, 0, 0)

And not getting the 0.5 I should be...

Message 8 of 30
jmreinhart
in reply to: Anonymous

jmreinhart
Advisor
Advisor

So let me explain the different types of normals.

 

Vertex-Face Normals
The polyVertexNormals command returns what's called the vertex-face normals. A vertex doesn't have normalsby itself, the normals cone from the adjacent faces. So the vertex-face normals are really the normals of those faces at the corner where the vertex is. That's why you get a list of 9 values (three vectors, one for each face). When you set the normal of the vertex to (.5,0,0) it changes all three of those vertex-face normals to (1,0,0), the normalized form of (.5,0,0).

 

You may have made a mistake when running your script because prior to editing any of the normals returned by

 

print(cmds.polyNormalPerVertex( query=True, xyz=True))

 

will be 

 

[1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 1.0, 0.0]

 

notice how one vector points in each of the three axis? Just like how the adjacent faces do.

 

Per-Vertex Normals

The other kind of vertex normal is the per-vertex normal which is a single vector created by doing a weighted sum of the vertex-face normals. That's what you can get from the api. Be aware that the true normals are not a simple average, they are a weighted average. From the API doc.

 

If angleWeighted is set to true, the normals are computed by an average of surrounding face normals weighted by the angle subtended by the face at the vertex. If angleWeighted is set to false, a simple average of surround face normals is returned.

The simple average evaluation is significantly faster than the angle-weighted average.

 

 

So the per-vertex normal you are getting is (.57,.57,.57). The reason it is .57 and not 1 is because it is normalized. The length of a vector (1,1,1) would be greater than 1. If a square had sides of length 1 then the diagonal would be greater than 1.

 
 
 

temp.png

 

I hope that helps you achieve what you are trying to do.

0 Likes

So let me explain the different types of normals.

 

Vertex-Face Normals
The polyVertexNormals command returns what's called the vertex-face normals. A vertex doesn't have normalsby itself, the normals cone from the adjacent faces. So the vertex-face normals are really the normals of those faces at the corner where the vertex is. That's why you get a list of 9 values (three vectors, one for each face). When you set the normal of the vertex to (.5,0,0) it changes all three of those vertex-face normals to (1,0,0), the normalized form of (.5,0,0).

 

You may have made a mistake when running your script because prior to editing any of the normals returned by

 

print(cmds.polyNormalPerVertex( query=True, xyz=True))

 

will be 

 

[1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 1.0, 0.0]

 

notice how one vector points in each of the three axis? Just like how the adjacent faces do.

 

Per-Vertex Normals

The other kind of vertex normal is the per-vertex normal which is a single vector created by doing a weighted sum of the vertex-face normals. That's what you can get from the api. Be aware that the true normals are not a simple average, they are a weighted average. From the API doc.

 

If angleWeighted is set to true, the normals are computed by an average of surrounding face normals weighted by the angle subtended by the face at the vertex. If angleWeighted is set to false, a simple average of surround face normals is returned.

The simple average evaluation is significantly faster than the angle-weighted average.

 

 

So the per-vertex normal you are getting is (.57,.57,.57). The reason it is .57 and not 1 is because it is normalized. The length of a vector (1,1,1) would be greater than 1. If a square had sides of length 1 then the diagonal would be greater than 1.

 
 
 

temp.png

 

I hope that helps you achieve what you are trying to do.

Message 9 of 30
Anonymous
in reply to: jmreinhart

Anonymous
Not applicable
So, I understand it's the normalized faces, that's clear to me, I think
the confusion is in what I thought the 9 values were. (I only asked if
they were xyzxyzxyz, not what they were).
What I'm trying to understand is why there is no function to return the
vertex normals that I can use to set another vertex normal.

V1n = V0n

All I'm trying to do is take the normals of a vertex and apply it to
another vertex to give it the exact same values. (Some verts don't have 3
faces, some are just a single vertex "quad") In the 2 examples I gave I
showed with the API library that it's not working the way I need, if it's
normalized or not.

So what would I need to do to take a vertex normal and apply it to another
one?
Thanks so much!

0 Likes

So, I understand it's the normalized faces, that's clear to me, I think
the confusion is in what I thought the 9 values were. (I only asked if
they were xyzxyzxyz, not what they were).
What I'm trying to understand is why there is no function to return the
vertex normals that I can use to set another vertex normal.

V1n = V0n

All I'm trying to do is take the normals of a vertex and apply it to
another vertex to give it the exact same values. (Some verts don't have 3
faces, some are just a single vertex "quad") In the 2 examples I gave I
showed with the API library that it's not working the way I need, if it's
normalized or not.

So what would I need to do to take a vertex normal and apply it to another
one?
Thanks so much!

Message 10 of 30
jmreinhart
in reply to: Anonymous

jmreinhart
Advisor
Advisor

MFnMesh::getVertexNormal()

MFnMesh::setVertexNormal()

0 Likes

MFnMesh::getVertexNormal()

MFnMesh::setVertexNormal()

Message 11 of 30
Anonymous
in reply to: jmreinhart

Anonymous
Not applicable

So I honestly can't figure this out. I've tried almost every setter I can and I still cannot return the vertex normals:

 

 

#manually setting the 2nd vertex to 2.0:
select -r pCube1.vtx[2] ;
polyNormalPerVertex -xyz 0.2 0 0;
// Result: polyNormalPerVertex1 // 

#running my code:
import maya.api.OpenMaya as om
import maya.cmds as cmds

selectionList = om.MSelectionList()
selectionList.add('pCube1')
dagPath = selectionList.getDagPath(0)
mesh = om.MFnMesh(dagPath)

vert = mesh.getVertexNormal(2, False, 4)

for v in vert:
    print(v)

 

Screenshot_8.png

What am I doing wrong? 

0 Likes

So I honestly can't figure this out. I've tried almost every setter I can and I still cannot return the vertex normals:

 

 

#manually setting the 2nd vertex to 2.0:
select -r pCube1.vtx[2] ;
polyNormalPerVertex -xyz 0.2 0 0;
// Result: polyNormalPerVertex1 // 

#running my code:
import maya.api.OpenMaya as om
import maya.cmds as cmds

selectionList = om.MSelectionList()
selectionList.add('pCube1')
dagPath = selectionList.getDagPath(0)
mesh = om.MFnMesh(dagPath)

vert = mesh.getVertexNormal(2, False, 4)

for v in vert:
    print(v)

 

Screenshot_8.png

What am I doing wrong? 

Message 12 of 30
mcw0
in reply to: Anonymous

mcw0
Advisor
Advisor

The "0.2, 0, 0" is normalized to "1, 0, 0".  So you are back to averaging and normalizing "1,0,0", "0,1,0" and "0,0,1".

The "0.2, 0, 0" is normalized to "1, 0, 0".  So you are back to averaging and normalizing "1,0,0", "0,1,0" and "0,0,1".

Message 13 of 30
Anonymous
in reply to: mcw0

Anonymous
Not applicable

Okay then I'm confusing myself here then, is there any way I can get a value that I can get the true normal values (Before normalization) and use those to apply to another vertex? 

OR a way to get them normalized so I can pass them directly into a setter? 

0 Likes

Okay then I'm confusing myself here then, is there any way I can get a value that I can get the true normal values (Before normalization) and use those to apply to another vertex? 

OR a way to get them normalized so I can pass them directly into a setter? 

Message 14 of 30
mcw0
in reply to: Anonymous

mcw0
Advisor
Advisor

I think you have 2 options when setting vertex normals.  You can set them to the face normal in which case, you will have 3 separate and distinct normals (1 for each face in the case of a corner vertex on a cube).  Or you can average the normals that you get when querying the normal of a vertex.

0 Likes

I think you have 2 options when setting vertex normals.  You can set them to the face normal in which case, you will have 3 separate and distinct normals (1 for each face in the case of a corner vertex on a cube).  Or you can average the normals that you get when querying the normal of a vertex.

Message 15 of 30
Anonymous
in reply to: mcw0

Anonymous
Not applicable

@mcw0 wrote:

I think you have 2 options when setting vertex normals.  You can set them to the face normal in which case, you will have 3 separate and distinct normals (1 for each face in the case of a corner vertex on a cube).  Or you can average the normals that you get when querying the normal of a vertex.


Thanks so much for your response, but here's the issue. 

 

I don't fully understand how I can average [(0.57735, -0.57735, 0.57735)] to get 0.2 in this case, and if I can somehow do it, where in the library can I do it? 

//Selecting the 2nd vertex in a cube and setting it to 0.2
select -r pCube1.vtx[2] ;
polyNormalPerVertex -xyz 0.2 0 0;
// Result: polyNormalPerVertex1 // 

//Code to getVertexNormals
import maya.api.OpenMaya as om
import maya.cmds as cmds

selectionList = om.MSelectionList()
selectionList.add('pCube1')
dagPath = selectionList.getDagPath(0)
mesh = om.MFnMesh(dagPath)

vert = mesh.getVertexNormals(True, 4)

for v in vert:
    print(v)

(-0.57735, -0.57735, 0.57735)
(0.57735, -0.57735, 0.57735)
(-0.57735, 0.57735, 0.57735)
(0.57735, 0.57735, 0.57735)
(-0.57735, 0.57735, -0.57735)
(0.57735, 0.57735, -0.57735)
(-0.57735, -0.57735, -0.57735)
(0.57735, -0.57735, -0.57735)

If I'm doing this wrong can you let me know, because as I understand this is the correct way to set and return vertex normals. 

 

When I GetVertexNormals() it's returning a normalized value, that I can't use (With any other Maya function to set a vertex)(And if I can use it to set another vertex normal, I don't know how, or I'm lost in the suggestions because I don't see how I can un normalize the normals, as there doesn't seem to be anything in the library that can do it).

For me it would make sense for the library to return a value from a getter that can be used in a setter, or am I just crazy?

 

So are you trying to say I can't use `getVertexNormal()` and `setVertexNormal()`? I have to get the face normals now?

 

If you could point me to the exact library functions to do what I'm trying to do I can figure it out. 

Take mesh1.vertex1.normal and apply the [0.2,0,0] to mesh2.vertex1.normal.

 

Thank you guys so much for your patience. 

0 Likes


@mcw0 wrote:

I think you have 2 options when setting vertex normals.  You can set them to the face normal in which case, you will have 3 separate and distinct normals (1 for each face in the case of a corner vertex on a cube).  Or you can average the normals that you get when querying the normal of a vertex.


Thanks so much for your response, but here's the issue. 

 

I don't fully understand how I can average [(0.57735, -0.57735, 0.57735)] to get 0.2 in this case, and if I can somehow do it, where in the library can I do it? 

//Selecting the 2nd vertex in a cube and setting it to 0.2
select -r pCube1.vtx[2] ;
polyNormalPerVertex -xyz 0.2 0 0;
// Result: polyNormalPerVertex1 // 

//Code to getVertexNormals
import maya.api.OpenMaya as om
import maya.cmds as cmds

selectionList = om.MSelectionList()
selectionList.add('pCube1')
dagPath = selectionList.getDagPath(0)
mesh = om.MFnMesh(dagPath)

vert = mesh.getVertexNormals(True, 4)

for v in vert:
    print(v)

(-0.57735, -0.57735, 0.57735)
(0.57735, -0.57735, 0.57735)
(-0.57735, 0.57735, 0.57735)
(0.57735, 0.57735, 0.57735)
(-0.57735, 0.57735, -0.57735)
(0.57735, 0.57735, -0.57735)
(-0.57735, -0.57735, -0.57735)
(0.57735, -0.57735, -0.57735)

If I'm doing this wrong can you let me know, because as I understand this is the correct way to set and return vertex normals. 

 

When I GetVertexNormals() it's returning a normalized value, that I can't use (With any other Maya function to set a vertex)(And if I can use it to set another vertex normal, I don't know how, or I'm lost in the suggestions because I don't see how I can un normalize the normals, as there doesn't seem to be anything in the library that can do it).

For me it would make sense for the library to return a value from a getter that can be used in a setter, or am I just crazy?

 

So are you trying to say I can't use `getVertexNormal()` and `setVertexNormal()`? I have to get the face normals now?

 

If you could point me to the exact library functions to do what I'm trying to do I can figure it out. 

Take mesh1.vertex1.normal and apply the [0.2,0,0] to mesh2.vertex1.normal.

 

Thank you guys so much for your patience. 

Message 16 of 30
mcw0
in reply to: Anonymous

mcw0
Advisor
Advisor

I think the problem is in your desire to set "0.2, 0, 0" and Maya normalizing the vector.  No matter what value you try to set, Maya will normalize the result.  No way around it that I know of.  So what you are saying, "0.2,0,0" to Maya will always be understood by Maya as "1,0,0".  

 

Can I ask what you are trying to achieve with an exact value of "0.2, 0, 0" that "1, 0, 0" won't suffice?

0 Likes

I think the problem is in your desire to set "0.2, 0, 0" and Maya normalizing the vector.  No matter what value you try to set, Maya will normalize the result.  No way around it that I know of.  So what you are saying, "0.2,0,0" to Maya will always be understood by Maya as "1,0,0".  

 

Can I ask what you are trying to achieve with an exact value of "0.2, 0, 0" that "1, 0, 0" won't suffice?

Message 17 of 30
Anonymous
in reply to: mcw0

Anonymous
Not applicable

So I need to be able to query a vertex normal that I can in turn apply to another vertex.

 

I was just using 0.2 as an example, since I was showing that the Open Maya functions getVertexNormal() doesn't return the value that I can use in my case.

 

So using the library functions how would I be able to take the normals from

mesh1.vertex[0] and set those values (Un normalized) to 

mesh2.vertex[0]

So they would both have the same vertex normals applied to them. I don't mind how I do it, I just need to do it. 😆

 

Everything that's been explained to me is leading me to believe there's no way to do this. 

0 Likes

So I need to be able to query a vertex normal that I can in turn apply to another vertex.

 

I was just using 0.2 as an example, since I was showing that the Open Maya functions getVertexNormal() doesn't return the value that I can use in my case.

 

So using the library functions how would I be able to take the normals from

mesh1.vertex[0] and set those values (Un normalized) to 

mesh2.vertex[0]

So they would both have the same vertex normals applied to them. I don't mind how I do it, I just need to do it. 😆

 

Everything that's been explained to me is leading me to believe there's no way to do this. 

Message 18 of 30
mcw0
in reply to: Anonymous

mcw0
Advisor
Advisor

Ok, if all you are doing is getting and setting, then you will never get a value of "0.2, 0, 0" because Maya always normalizes and that value will be "1, 0, 0".  So then you would use that to set the value as well.  So what was mentioned earlier should work for you:

 

MFnMesh::getVertexNormal()

MFnMesh::setVertexNormal()

 

Just remember that when you get the normal, it is returned for each vertex-face that the vertex belongs to.  So if there are 3 faces as in the corner of a cube, you will have 9 values that you will need to average.  If you don't want the average and are fine with a faceted look, then use polySetToFaceNormal.

0 Likes

Ok, if all you are doing is getting and setting, then you will never get a value of "0.2, 0, 0" because Maya always normalizes and that value will be "1, 0, 0".  So then you would use that to set the value as well.  So what was mentioned earlier should work for you:

 

MFnMesh::getVertexNormal()

MFnMesh::setVertexNormal()

 

Just remember that when you get the normal, it is returned for each vertex-face that the vertex belongs to.  So if there are 3 faces as in the corner of a cube, you will have 9 values that you will need to average.  If you don't want the average and are fine with a faceted look, then use polySetToFaceNormal.

Message 19 of 30
Anonymous
in reply to: mcw0

Anonymous
Not applicable

Okay, so when I was trying to use get and set vertexNormals() it's not working, same output I get with the Python library:
Screenshot_9.png

 

import maya.api.OpenMaya as om
import maya.cmds as cmds

selectionList = om.MSelectionList()
selectionList.add('pCube1')
dagPath = selectionList.getDagPath(0)
mesh = om.MFnMesh(dagPath)
vertnormal = mesh.getVertexNormal(2, True, 4)

selectionList.clear()
selectionList.add('pCube2')
dagPath = selectionList.getDagPath(0)
mesh = om.MFnMesh(dagPath)
mesh.setVertexNormal(vertnormal,2, 4)

 

I've manually set the 2nd vertex normal to 0.2 like all the other examples, and get the world space normal of it then try and set it, but you can see it's not working. So either I am completely lost on what library function I can use to just get the value and apply it to another vertex, or I'm not fully understanding and missing a step. 

 


Just remember that when you get the normal, it is returned for each vertex-face that the vertex belongs to.  So if there are 3 faces as in the corner of a cube, you will have 9 values that you will need to average.  If you don't want the average and are fine with a faceted look, then use polySetToFaceNormal.


I'm sorry I don't understand what I can do to average? Is there a function to do this for me? If not what can I do to get a value I can pass to a setter? 

 

Also this is a little confusing to me: "polySetToFaceNormal This command takes selected polygonal vertices or vertex-faces and changes their normals. If the option userNormal is used, the new normal values will be the face normals arround the vertices/vertex-faces. Otherwise the new normal values will be default values according to the internal calculation."

 

I want to select a single vertex, not vertices, or do I have to apply a normal to faces with the API?

 

Again thanks so much for your patience. 

0 Likes

Okay, so when I was trying to use get and set vertexNormals() it's not working, same output I get with the Python library:
Screenshot_9.png

 

import maya.api.OpenMaya as om
import maya.cmds as cmds

selectionList = om.MSelectionList()
selectionList.add('pCube1')
dagPath = selectionList.getDagPath(0)
mesh = om.MFnMesh(dagPath)
vertnormal = mesh.getVertexNormal(2, True, 4)

selectionList.clear()
selectionList.add('pCube2')
dagPath = selectionList.getDagPath(0)
mesh = om.MFnMesh(dagPath)
mesh.setVertexNormal(vertnormal,2, 4)

 

I've manually set the 2nd vertex normal to 0.2 like all the other examples, and get the world space normal of it then try and set it, but you can see it's not working. So either I am completely lost on what library function I can use to just get the value and apply it to another vertex, or I'm not fully understanding and missing a step. 

 


Just remember that when you get the normal, it is returned for each vertex-face that the vertex belongs to.  So if there are 3 faces as in the corner of a cube, you will have 9 values that you will need to average.  If you don't want the average and are fine with a faceted look, then use polySetToFaceNormal.


I'm sorry I don't understand what I can do to average? Is there a function to do this for me? If not what can I do to get a value I can pass to a setter? 

 

Also this is a little confusing to me: "polySetToFaceNormal This command takes selected polygonal vertices or vertex-faces and changes their normals. If the option userNormal is used, the new normal values will be the face normals arround the vertices/vertex-faces. Otherwise the new normal values will be default values according to the internal calculation."

 

I want to select a single vertex, not vertices, or do I have to apply a normal to faces with the API?

 

Again thanks so much for your patience. 

Message 20 of 30
mcw0
in reply to: Anonymous

mcw0
Advisor
Advisor

I just ran your code and it worked.  It took the average of pCube1.vtx[2] and applied it to pCube2.vtx[2].  Notice the yellow normal vector.  That is the average of the 3 vertex-face normals from pCube1.vtx[2].Capture2.PNG

0 Likes

I just ran your code and it worked.  It took the average of pCube1.vtx[2] and applied it to pCube2.vtx[2].  Notice the yellow normal vector.  That is the average of the 3 vertex-face normals from pCube1.vtx[2].Capture2.PNG

Can't find what you're looking for? Ask the community or share your knowledge.

Post to forums  

Autodesk Design & Make Report