I want to create a function that receives a mesh and a 2D coordinate as input and returns a point3 (maybe many) on the mesh where that 2D point lies, based on the UV coordinates of the mesh.

But it's not so easy though, as the input isn't at specific vertex locations, but anywhere in UV space. So it might or might not have any information at a given point. Not only that but it also can return multiple points, in case of overlapping faces in UV space.

In resume I'm looking for a function that looks like this: UV_To_Mesh_Sample theMesh theUV and returns an array of point3.

Regards,
Jr.

PiXeL_MoNKeY

07-25-2011, 04:30 PM

Look up Barycentric Coordinates (http://docs.autodesk.com/3DSMAX/14/ENU/MAXScript%20Help%202012/files/GUID-D1D7EB56-A370-4B07-99B4-BC779FB87CA-739.htm#WS73099CC142F48755-2231E4B3128F27E2F8C-336E) in the Maxscript Help.

-Eric

plastic

07-25-2011, 05:22 PM

Search for threads started by me with "uvw" in the title.
I got some half-working solution. The problem is that it only works with default uvw maps on primitives, not with a uvw map modifier, as far as I remember. The whole uvw thing in max is a nightmare, IMO.

Bobo

07-25-2011, 05:32 PM

Search for threads started by me with "uvw" in the title.
I got some half-working solution. The problem is that it only works with default uvw maps on primitives, not with a uvw map modifier, as far as I remember. The whole uvw thing in max is a nightmare, IMO.

Not really, you can call snapshotAsMesh() to get the TriMesh of any object, the rest is trivial meshOp. mapping calls (there is a whole section in the help about accessing all 100 map channels in a mesh).

denisT

07-25-2011, 05:36 PM

I want to create a function that receives a mesh and a 2D coordinate as input and returns a point3 (maybe many) on the mesh where that 2D point lies, based on the UV coordinates of the mesh.
In resume I'm looking for a function that looks like this: UV_To_Mesh_Sample theMesh theUV and returns an array of point3.

do it step by step...
step #1: can you make a function to check if some 2D point inside some 2D triangle?
we need this function to find all UV faces which contain the UV point.

Eugenio

07-25-2011, 11:04 PM

Thanks a lot for the answer guys. But I'm still stuck in this problem...I did most of what you told me already, but as I didn't want to get into the details of my tries to keep the post as short as possible.

step #1: can you make a function to check if some 2D point inside some 2D triangle?we need this function to find all UV faces which contain the UV point.I already did a function to find the Barycentric Coordinates. However that's not my main problem.

Suppose I have this part up and running. Like say, I pass the coordinates [0.3, 0.2, 0] in UVW space and I find 3 faces containing that point. Fine. But what I really need is where in 3D space the point [0.3, 0.2, 0] actually lies for each face. To my logic seems more like the inverse of the barycentric coordinates, something I don't know how to do.

Another problem is that I'm going to have too many geometry queries, because at every step the script goes in 2D, I have to go through all triangles in the mesh to check if it falls inside a face or faces. Maybe there's an easier way of doing this, but I really can't see other than using acceleration structures and that is far more trouble this script deserves.

Actually if it gets too complicated I have to give up on the idea because there's no time to develop it...

Purpose of the script: This is my reference: http://www.youtube.com/watch?v=rUFnH7KYMFE.
I have to do something similar, and I already got a nice procedural pattern, so I was looking for a method of wrapping it into arbitrary meshes. The best idea that came to mind was generating it in UV space and converting the values to 3D.

Regards,
Jr.

plastic

07-25-2011, 11:11 PM

well here is what I got:

(
delete $Point*

local meshObj = snapShotAsMesh $
local theChannel=1

local stepsU=5 as Double
local stepsV=5 as Double
local totalSteps=stepsU*stepsV

Result:
Grid of point helpers with 5 subdivs on U and V on a box with default mapping:
http://666kb.com/i/bp57soayfmztv3lrw.png
For a given UV coordinate, there are 6 points in world space, in this case (box mapping).

There is a problem with this code I couldn't figure out.
When the original box is segmented, something strange happens, probably related to a rounding error? when uv point lies on a edge then the corresponding face cant be found...or something... :shrug:

http://666kb.com/i/bp95kmn5io3c5bo58.jpg

http://666kb.com/i/bp95qvnlezylt83cs.jpg

Eugenio

07-27-2011, 01:02 AM

Plastic, thanks a ton man! Although I was almost done, you still helped me. I finally managed to resolve my main issues! :bounce:
My code seems to be working nicely, but it's still wip. I didn't care about UV Tiling for now as I'm probably not going to need it. At least it respects correctly the mapping coordinates.

There are problems of course, but are not so apparent in the code below because I'm just creating point helpers at sample points, but as for my needs I must create a spline out of those, so they must be created in proper order otherwise the spline will look like a mess.

Now I need to think in a way to optimize it as as I said it goes through all the mesh for every sample point. Any suggestion is again very welcome... :thumbsup:

And I'm doing a really nasty trick converting a float to string and the string back to float to get around a maxscript inaccuracy comparing a variable to 1.0. I'm not sure the best (and faster) solution for that.

To try out the code just copy it and create a new script and with some object selected run it.
NOTE: Coordinates with tiling (values out of 0-1 range) will not be taken into account.

--Calculates the total area of the parallelogram formed by the triangle
ta = length (cross (v1-v2) (v3-v2))

a1 = cross edge1 edge3
a2 = cross edge2 edge3
a3 = cross edge2 edge1

bc1 = length (a1/ta)
bc2 = length (a2/ta)
bc3 = length (a3/ta)

theTotal = (bc1 + bc2 + bc3) as string

--If the sum of the three components of the barycentric coordinates is bigger than one it means the point is outside the triangle
if theTotal as float <= 1.0 then
bc = [bc1, bc2, bc3]
else
bc = undefined

)

for v=0 to 1 by 1/step do
for u=0 to 1 by 1/step do
for f=1 to theNumFaces do
(
--Returns the barycentric coordinates in UV space for a given UVW point
bc = find_barycoords_fn obj f [u, v, 0]

Hey Eugenio,
I'm looking forward trying your code but I'm on vacation right now and cant test it with my laptop. Will give it a run in a few days.
For the comparing float issue, you may try using the closeEnough() function, instead of a "==" compare.
Also try converting your numerical values to "Double" precision instead of the default "Float".

CGTalk Moderation

07-27-2011, 03:35 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.