c++visual-studiomayamaya-api

Trying to deform any mesh into a sphere. How to translate the vertex position to lie on a sphere?


I am trying to write a deformer script for maya, using the maya API which deforms any mesh into a sphere by translating it's vertices.

What i already have is a deformer which translates every vertex of mesh in the direction of it's normal with the amount specified. This is done using the below equation.

point += normals[itGeo.index()] * bulgeAmount * w * env;

Where, point is the vertex on the mesh. normals[itGeo.index()] is a vector array which represents the normals of each vertex. w and env are to control the weights of the deformation and the envelope.

What this code basically does is, it translates the vertex in the direction of the normal with the amount specified. While this works for a sphere, because a sphere's vertex normals would point at the center. It would not work for other meshes as the normals would not point at the center of the mesh.


    float bulgeAmount = data.inputValue(aBulgeAmount).asFloat();
    float env = data.inputValue(envelope).asFloat();
    MPoint point;
    float w;
    for (; !itGeo.isDone(); itGeo.next())
    {
        w = weightValue(data, geomIndex, itGeo.index());

        point = itGeo.position();

        point += normals[itGeo.index()] * bulgeAmount * w * env;

        itGeo.setPosition(point);
    }

I initially thought changing the direction of translation would solve the problem. As in, if we can find the vector in the direction from the center of the mesh to each vertex and translate it along that direction for an amount specified would solve it. Like so :

point += (Center - point) * bulgeAmount * w * env;

Where, Center is the center of the mesh. But this does not give the desired result. I also would want the deformer to be setup in such a way that the user can input radius "r" value and can also change the amount attribute from 0 to 1 to deform the mesh from it's original state to a spherical one. So that he can choose a value in between if her desires and the mesh would be something between a sphere and it's original shape.

This is my very first post in stackOverflow. I apologize if the format does not follow the community expectations. Any help on this will be greatly appreciated.

Thank You.


Solution

  • About the direction:

    I think your line : point += (Center - point) * bulgeAmount * w * env;

    is a good starting point. But instead of using (Center - point), you should use its opposite, (point-Center) and normalize it before using it. If you don't use a normalized version of this (point-Center) vector, every vertex will be translated to a wrong position.

    About your variation between 0.0 (original) to 1.0 (sphere):

    If Po is the original position
    If Pf is the final position
    If d is the original distance between the point Po and the Center C: d=norm(Center - point) = norm(C-Po)
    If Direction is (Center - point)/d (so normalized, as explained above)

    What we want:
    At r=0.0 your vertex must stay at its original position: Pf = Center + Direction * d

    At r=1.0 your vertex must stick to the sphere of radius R: Pf = Center + Direction * R

    And if we generalize:

    Pf = C + Direction * ( r*R + (1-r)*d )

    With d = norm(C-Po)
    Direction = (C-Po)/d
    R the radius of your sphere
    and r a user param between [0.0; 1.0]

    Not sure I am clear enough, I'm not used neither to answer here :) Best