PDA

View Full Version : mapVertices... again (or never again?)


prettyPixel
03-10-2005, 05:17 PM
Hello,

Here is a problem i'm unable to solve:
I cannot find the correspondence between vertex UV's and vertex positions in Polys...
Ok, i've read the procedure for meshes, i tried it and it works fine, but as soon as i want to apply this method to polys, there's no more correspondence.

So, for each face, i get the vertices positions and the vertices UVWcoords, and they don't match!!!

here is the code to create my test object :

max modify mode
obj=plane Length_Segments:2 Width_Segments:2 length:1.0 width:1.0 pos:[0.5,0.5,0] mapCoords:true
select obj
obj.wirecolor=blue
convertToPoly obj
addModifier obj (Unwrap_UVW ())
objModUnwrap=obj.modifiers[1].unwrap
objModUnwrap2=obj.modifiers[1].unwrap2
objModUnwrap.setMapChannel 1
objModUnwrap.edit()
objModUnwrap.displayMap false
objModUnwrap2.setGridVisible false
objModUnwrap2.setTVSubObjectMode 3
objModUnwrap2.setTVElementMode false
for f=obj.numfaces to 1 by -1 do
(
objModUnwrap2.selectFaces #{f}
objModUnwrap.breakSelected()
)
objModUnwrap2.selectFaces #{}
convertToPoly obj

ok now you have the same object as me: a plane with 4 faces (2 by 2)
Each mapFace is independent to to others.

the object datas:

http://users.skynet.be/arketip/CGtalk/note.jpg

face 1 for example:
vertsOfFace=#(1, 2, 4, 5) -- the vertices of the face
mapVertsOfFace=#(13, 1, 15, 16) -- the MAPvertices of the same face
coord mapVertsOfFace[1]=[0,0.5,0] -- the coordinates of MAPvertices (to localize them in the object)
coord mapVertsOfFace[2]=[0,0,0]
coord mapVertsOfFace[3]=[0.5,0,0]
coord mapVertsOfFace[4]=[0.5,0.5,0]


It seems that the order of the vertices in an face don't match the order of the MAPvertices...

http://users.skynet.be/arketip/CGtalk/note2.jpg

if you wish it, Here's the code to print the values :

clearListener()
obj=selection[1]
for f=1 to obj.numFaces do
(
vertsOfFace=(polyOp.getVertsUsingFace Obj #{f})as array
mapVertsOfFace=polyOp.getMapFace obj 1 f
print("\nface f="+f as string)
print("vertsOfFace="+vertsOfFace as string)
print("mapVertsOfFace="+mapVertsOfFace as string)
for i=1 to mapVertsOfFace.count do
(
cmv=mapVertsOfFace[i]
coord=polyOp.getMapVert obj 1 cmv
print("coord mapVertsOfFace["+i as string+"]="+coord as string)
)
)--for f

Is the procedure of the help file "Understanding Textures coordinates" applicable to Polys ?
Can anyone say me if It's possible to find the correspondence ?
Anybody has not ever made that?

What's wrong with my code?

I'm stucked...

Thanks in advance for your help

Prettypixel

prettyPixel
03-12-2005, 07:09 PM
Apparently, you can get back a vertex from a map vertex, but not the opposite.
Not directly...

Then, I used a function wich bobo put on the forum in answer to one of my questions.
Thanks to this function, I programmed the inverse function using the first.
It is complex but it works.

The function programmed by bobo:

fn getVertsUsingMapVert theObj theMapChannel theIndex =
(
correspondingVertices = #{} --init. a bitarray
numFaces = polyOp.getNumMapFaces theObj theMapChannel --get the number of map faces
for f = 1 to numFaces do --go through all of them
(
theMapFace = polyOp.getMapFace theObj theMapChannel f --get the list of vertices defining the map face
checkForVertex = findItem theMapFace theIndex --see if the searched one is there
if checkForVertex > 0 then --if it is,
(
polyFace = polyOp.getFaceVerts theObj f --get the list of vertices in the poly face
append correspondingVertices polyFace[checkForVertex] --add to the bitarray
)
)
correspondingVertices --return the result
)

The inverse function:

fn getMapVertsUsingVert theObj theMapChannel theIndex =
(
correspondingMapVertices = #{} --init. a bitarray
facesList=polyOp.getFacesUsingVert theObj #{theIndex} --get the faces of vertex
for currentFace in facesList do --go through all of them
(
theMapFace = polyOp.getMapFace theObj theMapChannel currentFace --get the list of vertices defining the map face
for mapVert in theMapFace do --go through all of them
(
vertsBitArray=getVertsUsingMapVert theObj theMapChannel mapVert -- get the list of vertices using the map vertex
if findItem vertsBitArray theIndex!=0 do append correspondingMapVertices mapVert -- add to the bit array if it's present
)
)
correspondingMapVertices --return the result
)

I think about a way of simplifying it by storing the values in a array...

prettyPixel
03-13-2005, 12:29 AM
(I erased the message copied twice by mistake)

prettyPixel
03-13-2005, 12:34 AM
Here is a way to simplify this and especially of making it faster.
Indeed, every time I use the function "getVertsUsingMapVert", all the faces are inspected !
And what's worse with "getMapVertsUsingVert", they are 16 times inspected (if the object have 4 sides polys).

If you use them only for one vertex or 2, it is not very important
but imagine to scan thousand of vertices of an hires poly... impraticable!
For example: with an object of 9800 faces and 5041 vertices.
If I use for each of the points of the object the function " getMapVertsUsingVert " faces will be inspected:
5041 x 9800 x 16 = 790.428.800 times!!!

The best solution is to look at the faces only once and to store the data in a array.
The array creates allows also to find easily the vertices and the map Vertices of an object.

Here is the code to create the 2 array:

fn getArrayOfMapVerts2Verts theObj theMapChannel =
(
mapVerts2Verts = #()
numMapFaces = polyOp.getNumMapFaces theObj theMapChannel
for f = 1 to numMapFaces do
(
theMapFace = polyOp.getMapFace theObj theMapChannel f
for mv=1 to theMapFace.count do
(
mapVert = theMapFace[mv]
polyFace = polyOp.getFaceVerts theObj f
if mapVerts2Verts[mapVert] == undefined
then mapVerts2Verts[mapVert] = #(polyFace[mv])
else ( if findItem mapVerts2Verts[mapVert] polyFace[mv] == 0 do append mapVerts2Verts[mapVert] polyFace[mv] )
)
)
mapVerts2Verts
)

fn getArrayOfVerts2MapVerts mapVerts2Verts =
(
verts2MapVerts=#()
for mv=1 to mapVerts2Verts.count do
(
currentVerts=mapVerts2Verts[mv]
for v=1 to currentVerts.count do
(
if verts2MapVerts[currentVerts[v]] == undefined
then verts2MapVerts[currentVerts[v]]=#(mv)
else append verts2MapVerts[currentVerts[v]] mv
)
)
verts2MapVerts
)

And with a "print utility" (don't use it with an object that have more than 500 vertices because the print is slow)

utility printMapVertices "printMapVertices"
(
button printMapVertices_osd "print mapvertices to listener"

fn getArrayOfMapVerts2Verts theObj theMapChannel =
(
mapVerts2Verts = #()
numMapFaces = polyOp.getNumMapFaces theObj theMapChannel
for f = 1 to numMapFaces do
(
theMapFace = polyOp.getMapFace theObj theMapChannel f
for mv=1 to theMapFace.count do
(
mapVert = theMapFace[mv]
polyFace = polyOp.getFaceVerts theObj f
if mapVerts2Verts[mapVert] == undefined
then mapVerts2Verts[mapVert] = #(polyFace[mv])
else ( if findItem mapVerts2Verts[mapVert] polyFace[mv] == 0 do append mapVerts2Verts[mapVert] polyFace[mv] )
)
)
mapVerts2Verts
)

fn getArrayOfVerts2MapVerts mapVerts2Verts =
(
verts2MapVerts=#()
for mv=1 to mapVerts2Verts.count do
(
currentVerts=mapVerts2Verts[mv]
for v=1 to currentVerts.count do
(
if verts2MapVerts[currentVerts[v]] == undefined
then verts2MapVerts[currentVerts[v]]=#(mv)
else append verts2MapVerts[currentVerts[v]] mv
)
)
verts2MapVerts
)

on printMapVertices_osd pressed do
(
obj=selection[1]
channel=1
mapVerts2Verts=getArrayOfMapVerts2Verts obj channel -- create the array mapVerts ==> verts
verts2MapVerts=getArrayOfVerts2MapVerts mapVerts2Verts -- create the array verts ==> mapVerts
-- show in listener
clearListener()
format "\narray : mapVerts2Verts\n======================\n"
for i=1 to mapVerts2Verts.count do format "mapVert % => verts %\n" i mapVerts2Verts[i]
format "\narray : verts2MapVerts\n======================\n"
for i=1 to verts2MapVerts.count do format "vert % => mapVerts %\n" i verts2MapVerts[i]
)

)--utility

Here is a performance test really satisfactory:
I have scanned an object with 651 verts / 600 faces and:
- for every vertice I found the mapvertices array
- for every mapvertices I found the vertices array
using getVertsUsingMapVert + getMapVertsUsingVert : 88391 milliseconds
using the array :getArrayOfMapVerts2Verts + getArrayOfVerts2MapVerts : 31 milliseconds

pretty good ;)

prettyPixel
03-14-2005, 02:39 AM
If anybody interested (and I know at least one person in this case), here is a new version that support also mesh objects.

utility printMapVertices "printMapVertices"
(
button printMapVertices_osd "print mapvertices to listener"

fn getArrayOfMapVerts2VertsPOLY theObj theMapChannel =
(
mapVerts2Verts = #()
numMapFaces = polyOp.getNumMapFaces theObj theMapChannel
for f = 1 to numMapFaces do
(
theMapFace = polyOp.getMapFace theObj theMapChannel f
polyFace = polyOp.getFaceVerts theObj f
for mv=1 to theMapFace.count do
(
mapVert = theMapFace[mv]
if mapVerts2Verts[mapVert] == undefined
then mapVerts2Verts[mapVert] = #(polyFace[mv])
else ( if findItem mapVerts2Verts[mapVert] polyFace[mv] == 0 do append mapVerts2Verts[mapVert] polyFace[mv] )
)
)
mapVerts2Verts
)

fn getArrayOfMapVerts2VertsMESH theObj theMapChannel =
(
mapVerts2Verts = #()
numMapFaces = meshOp.getNumMapFaces theObj theMapChannel
for f = 1 to numMapFaces do
(
theMapFace = meshOp.getMapFace theObj theMapChannel f
theMapFace = #(theMapFace.x as integer,theMapFace.y as integer,theMapFace.z as integer)
meshFace = getFace theObj f
meshFace = #(meshFace.x as integer,meshFace.y as integer,meshFace.z as integer)
for mv=1 to theMapFace.count do
(
mapVert = theMapFace[mv]
if mapVerts2Verts[mapVert] == undefined
then mapVerts2Verts[mapVert] = #(meshFace[mv])
else ( if findItem mapVerts2Verts[mapVert] meshFace[mv] == 0 do append mapVerts2Verts[mapVert] meshFace[mv] )
)
)
mapVerts2Verts
)

fn getArrayOfMapVerts2Verts theObj theMapChannel =
(
array=false
case classOf theObj of
(
Editable_mesh: array=getArrayOfMapVerts2VertsMESH theObj theMapChannel
Editable_Poly: array=getArrayOfMapVerts2VertsPOLY theObj theMapChannel
)
array
)

fn getArrayOfVerts2MapVerts mapVerts2Verts =
(
verts2MapVerts=#()
for mv=1 to mapVerts2Verts.count do
(
currentVerts=mapVerts2Verts[mv]
for v=1 to currentVerts.count do
(
if verts2MapVerts[currentVerts[v]] == undefined
then verts2MapVerts[currentVerts[v]]=#(mv)
else append verts2MapVerts[currentVerts[v]] mv
)
)
verts2MapVerts
)

on printMapVertices_osd pressed do
(
clearListener()
if selection.count!=0 then
(
obj=selection[1]
channel=1
mapVerts2Verts=getArrayOfMapVerts2Verts obj channel -- create the array mapVerts ==> verts
if mapVerts2Verts!=false then
(
verts2MapVerts=getArrayOfVerts2MapVerts mapVerts2Verts -- create the array verts ==> mapVerts
format"%\n" obj.name
format "\narray : mapVerts2Verts\n======================\n"
for i=1 to mapVerts2Verts.count do format "mapVert % => verts %\n" i mapVerts2Verts[i]
format "\narray : verts2MapVerts\n======================\n"
for i=1 to verts2MapVerts.count do format "vert % => mapVerts %\n" i verts2MapVerts[i]
)
)
)

)--utility

CGTalk Moderation
03-14-2005, 02:39 AM
This thread has been automatically closed as it remained inactive for 12 months. If you wish to continue the discussion, please create a new thread in the appropriate forum.