Issues with the space maya returns from M3dView.viewToWorld and meshFn.allIntersect

So I have a tool that works just the way I want it to when maya is in cm units. However any other one and the positions returned seem off by a fairly consistent basis (like the units are in a slighty different space). So, my first question is:

Does M3dView.viewToWorld not return in your current preference unit setting?

Any advice on working through this?

Googled a good bit and wasn’t finding much to go on. All of my calls are calling for world space coordinates. From my own testing and also looking at the old parentToSurface.mel from autodesk it looks like they’re converting on the fly for some of the return info via:

proc float convertToCmFactor()
{
	string $unit = `currentUnit -q -linear`;
	if( $unit == "mm" ){
		return( 0.1 );
	} else if( $unit == "cm" ){
		return( 1.0 );
	} else if( $unit == "m" ){
		return( 100.0 );
	} else if( $unit == "in" ){
		return( 2.54 );
	} else if( $unit == "ft" ){
		return( 30.48 );
	} else if( $unit == "yd" ){
		return( 91.44 );
	} else {
		return( 1.0 );
	}
}

I guess I’m just perplexed that you can’t get the correct space info via the api by regular call. Can anyone shed light?

Thanks!
j

I remember writing an exporter 2 years ago and I am 100% sure that none of the maya preference stuff applies to the API. What you get is the units and that’s it. Whether it’s in meters or centimeters is up to you and the API doesn’t care about that. So if you have 100 in your translateX, Y, Z that’s what it’s gonna return.

You will have to convert the values yourself.

Thanks for the heads up, Lonewolf:)

It appears that maya’s world space unit is always centimeters and any conversion has to be based off that assumption. The tool is now working in all modes.

This is my working converter for the sake of anyone running into this:

import maya.cmds as mc
def returnMayaSpaceFromWorldSpace(value):
    """
    Thanks to parentToSurface.mel from autodesk for figuring out this was necessary
    
    
    """
    unit = mc.currentUnit(q=True,linear=True)
	
    if unit == 'mm':
	return (value * 10)
    elif unit =='cm':
	return value
    elif unit =='m':
	return(value * .01)
    elif unit == 'in':
	return(value * 0.393701)
    elif unit == 'ft':
	return(value * 0.0328084)
    elif unit =='yd':
	return(value * 0.0109361)
    else:
	return value
    
def returnWorldSpaceFromMayaSpace(value):
    """
    Thanks to parentToSurface.mel from autodesk for figuring out this was necessary
        
    """
    unit = mc.currentUnit(q=True,linear=True)
	
    if unit == 'mm':
	return (value * .1)
    elif unit =='cm':
	return value
    elif unit =='m':
	return(value * 100)
    elif unit == 'in':
	return(value * 2.54)
    elif unit == 'ft':
	return(value * 30.48)
    elif unit =='yd':
	return(value * 91.44)
    else:
	return value

cm is what Maya is written in ( it’s why, for example, you get useless camera clip values as default if you use other units).

Most user-facing calls (mel or python) are in the current units. However there are a handful of things ( selectionConstraints and NURBS fillet/bevel sizes come to mind, but I know there are others) that are always in cm regardless. I use more or less the same code you have when I care about real world units… and every time i do, I curse the lazy implementation that makes it necessary to do so.

Thanks, Theodox:) Yeah, I’m relatively new to maya api stuff and assumed that return calls would be in the preference units like everything else I’d been working with. I’d have just been happy if the docs spelled it out. A simple, hey, these units are in cm for the worldSpace flags in the api docs.

Live and learn, I reckon.

It’s not documented on the API because the units are not cm and vice-versa. Matrices has no concept of cm or m as far as the API is concerned. It’s the maya frontend gui that provides that type of feature through mel which happens to default 1 unit to 1 cm, which again could easily be ignored and redefined by your own tools by providing the custom transformers.

Lonewolf, if it isn’t actually a cm why is that the only unit of measurement that functions properly at a 1.0 factor? A unit of distance must mean something tangible and definable to have any practical purpose. If an api return says a worldspace distance is 1.0, the user needs to know if that 1unit matches the other 1 unit measurements they’ve already gotten via regular worldspace xform calls or whatever.

I don’t see how there is a real difference. If there is, please let me know.

I think that matrices aren’t, strictly speaking, unitless – the translate bit does represent a distance which has to resolve into units at some point. The UI tends to hide this fact by translating attribs that are part of the matrix into or out of world units – but the internal storage does not change, it’s always in cm. You’re both basically right – it’s abstract units but they default to being interpreted as cm.

As an experiment, look at the difference between the results of xform(t=True) and xform(m=True) for the same object under different unit settings: when I tried it, I found that the translate query returns in the current units (so it changes as you reset the units) but the matrix always returns the same thing – and that same thing is equivalent to the answer you get from the translate query under cm (the translate part of the matrix being the items 12, 13, and 14 of the 0-15 return value) .

It seems like what Maya does is apply the unit translation before editing matrix values, so if you do matrix math you must always turn your doubles into cm on the input size and interpret results of matrix operations as if they were cm. The few places where there are holes in this (eg polySelectConstraint) probably represent somebody at Adsk forgetting to add the boilerplate code to do this in their own stuff.

1 Like

Thanks Theodox and thanks for the example. I’d planned on messing with that first thing in the mornin:)

[QUOTE=Theodox;18423]It seems like what Maya does is apply the unit translation before editing matrix values[/QUOTE]
Yeah, that’s what I ment with frontend. The concept of a unit comes into play only when we want to relate to another unit.