MEL How-To #102

Back · Previous · Next Maya

How do I convert between Maya's internal linear unit ('cm') and the unit which is represented in the UI?

Below are two procedures that may be used to convert between Maya's internal unit and the UI unit.

proc float internalToUI( float $value )
{
  // Query Maya's UI linear unit.
  //
  string $unit = `currentUnit -q -l`;

  // Default ('cm') is unchanged.
  //
  float $factor = 1.0;

  // Factor used to convert Maya's internal "cm"
  // to the following units.
  //
  switch ( $unit )
  {
      case "in":
          $factor =  0.393700787;
          break;
      case "ft":
          $factor =  0.032808399;
          break;
      case "yd":
          $factor =  0.010936133;
          break;
      case "mi":
          $factor =  0.000006214;
          break;
      case "mm":
          $factor = 10.000000000;
          break;
      case "km":
          $factor =  0.000010000;
          break;
      case "m":
          $factor =  0.010000000;
          break;
  }

  // Adjust the value by the appropriate factor.
  //
  $value *= $factor;

  return $value;
}
proc float uiToInternal( float $value )
{
  // Query Maya's UI linear unit.
  //
  string $unit = `currentUnit -q -l`;

  // Default ('cm') is unchanged.
  //
  float $factor = 1.0;

  // Factor used to convert the following units
  // to Maya's internal "cm".
  //
  switch ( $unit )
  {
      case "in":
          $factor =      2.540000000;
          break;
      case "ft":
          $factor =     30.480000000;
          break;
      case "yd":
          $factor =     91.440000000;
          break;
      case "mi":
          $factor = 160934.400000000;
          break;
      case "mm":
          $factor =      0.100000000;
          break;
      case "km":
          $factor = 100000.000000000;
          break;
      case "m":
          $factor =    100.000000000;
          break;
  }

  // Adjust the value by the appropriate factor.
  //
  $value *= $factor;

  return $value;
}

Here's an example use:

  // Maya is configured to use 'meter' as its UI unit.
  //
  currentUnit -q -l;
  // Result: m //

  internalToUI( 3.14 );
  // Result: 0.0314 //

  uiToInternal( 3.14 );
  // Result: 314 //

As a bit of "Making of..." trivia, here's the API code I whipped up to generate the switch statements in the above procedures:

const unsigned int numUnits = 8;
unsigned int u;

const MDistance::Unit unit[numUnits] =
{
    MDistance::kInches,
    MDistance::kFeet,
    MDistance::kYards,
    MDistance::kMiles,
    MDistance::kMillimeters,
    MDistance::kKilometers,
    MDistance::kMeters
};

const char* unitNames[numUnits] =
{
    "in",
    "ft",
    "yd",
    "mi",
    "mm",
    "km",
    "m"
};

MDistance distance( 1.0, MDistance::kCentimeters );

// internalToUI
//

clog << "// internalToUI" << endl;
clog << "// Factor used to convert Maya's internal \"cm\"" << endl;
clog << "// to the following units." << endl;
clog << "//" << endl;
clog << "switch ( $unit )" << endl << "{" << endl;
for ( u = 0; u < numUnits; u++ )
{
    clog << "    case \"" << unitNames[u] << "\":" << endl;
    clog << "        $factor = ";
    clog << setiosflags(ios::fixed) << setprecision(9);
    clog << distance.as( unit[u] ) << ";" << endl;
    clog << "        break;" << endl;
}
clog << "}" << endl;

// uiToInternal
//

clog << "// uiToInternal" << endl;
clog << "// Factor used to convert the following units" << endl;
clog << "// to Maya's internal \"cm\"." << endl;
clog << "//" << endl;
clog << "switch ( $unit )" << endl << "{" << endl;
for ( u = 0; u < numUnits; u++ )
{
    distance.setUnit( unit[u] );
    clog << "    case \"" << unitNames[u] << "\":" << endl;
    clog << "        $factor = ";
    clog << setiosflags(ios::fixed) << setprecision(9);
    clog << distance.as( MDistance::kCentimeters ) << ";" << endl;
    clog << "        break;" << endl;
}
clog << "}" << endl;

31 Jul 2004