# How can I convert coordinates from global to local CS in Mechanical?

Options
Member, Moderator, Employee Posts: 103

When I select an entity in Mechanical, I can choose a coordinate system to display coordinates in the selection information. Is there a way to do it by script?

Tagged:

• Member, Moderator, Employee Posts: 103
edited November 2023
Options

Here's an example for converting coordinates to a local coordinate system. Pay attention to proper unit conversions. The example works on cartesian coordinate systems and would require little work to apply to cylindrical CS as well.

```def convertToCS(coords,cs_name,convert=True):
# Converts coordinates to a given coordinate system
# If convert=True, 'coords' is assumed to be in users unit
# If convert=False, 'coords' must be in meters
import units

# Retrieve conversion factor from current length unit to meters
toUnit = "m" # Always generate the result to display in SI unit
fromUnit=ExtAPI.DataModel.AnalysisList[0].CurrentConsistentUnitFromQuantityName("Length")
convFact = units.ConvertUnit(1, fromUnit, toUnit, "Length")

# Retrieve axis from coordinate system
# Assume cs_name is unique (if not, the first one will be used)
csM = ExtAPI.DataModel.GetObjectsByName(cs_name)[0]
csXAxis = csM.XAxis
csYAxis = csM.YAxis
csZAxis = csM.ZAxis

# Convert to 3D vectors
xAxis = Vector3D(csXAxis[0], csXAxis[1], csXAxis[2])
yAxis = Vector3D(csYAxis[0], csYAxis[1], csYAxis[2])
zAxis = Vector3D(csZAxis[0], csZAxis[1], csZAxis[2])

# create transformation matrix
# We use a 4x4 matrix with rotation and translations
idM  =  Matrix4D()
transM = idM.CreateSystem(xAxis,yAxis,zAxis)
# Transpose to ensure proper transformation from global to local
transM.Transpose()

# Translation part of the transformation matrix
origin=csM.Origin # Origin will be in user units, so convert to m
origin_transfd=transM.Transform(Vector3D(origin[0],origin[1],origin[2]))

for i in range(0,3):
transM[12+i]=-origin_transfd[i]

# Now convert point to new CS
# First convert to meters if needed
if convert:
vec=Vector3D(coords[0]*convFact, coords[1]*convFact, coords[2]*convFact)
else:
vec=Vector3D(coords[0], coords[1], coords[2])

# Rotate
vec_transfd=transM.Transform(vec)

# Return new coordinates in user units
if convert:
invFact=1/convFact
return [vec_transfd[0]*invFact,vec_transfd[1]*invFact,vec_transfd[2]*invFact]
else:
return [vec_transfd[0],vec_transfd[1],vec_transfd[2]]

# Test function on current selection's centroid
cursel=ExtAPI.SelectionManager.CurrentSelection
# using convert=False in function call as Centroid is always in meters
print(convertToCS(cursel.Entities[0].Centroid,'myCS',False))
```
• Member, Employee Posts: 243
Options

Here are some similarly useful functions.

• Member Posts: 14
Options

When I try to run this function, it seems return a wrong result.
when I made some modification. Then it works (only tested for Mechanical unit in "mm")
I'm not sure is that a correct modification?
And, is .Centroid always return in "m"?

```convFact = units.ConvertUnit(1, fromUnit, toUnit, "Length")
```

to

```convFact = units.ConvertUnit(1, toUnit, fromUnit, "Length")

```

and

```if convert:
invFact=1/convFact
```

to

```    if not convert:
```
• Member, Employee Posts: 243
Options

I believe .Centroid uses this unit:
`ExtAPI.Graphics.Unit`

• Member Posts: 14
Options

@Landon Mitchell Kanner said:
I believe .Centroid uses this unit:
`ExtAPI.Graphics.Unit`

I checked `ExtAPI.Graphics.Unit`, it seems the value was not changed with the mechanical unit setting or graphics. So, what is this value really is?

And which value will change with the mechanical unit setting?

• Member, Moderator, Employee Posts: 103
Options

@ZZ.tang the internal geometry is I believe always in m and ExtAPI.Graphics.Unit is there constant to "m".

If you want to grab the current user unit, you can use this:

`lunit=DataModel.CurrentUnitFromQuantityName("Length")`

• Member, Employee Posts: 243
edited December 2023
Options

ExtAPI.Graphics.Unit is the internal geometry units, which depends on the CAD file and how you imported it. It is usually meters but not always. This is the unit for face.Centroid that you asked about.

You can view this unit under Geometry > Definition > Length Unit:

@Pierre Thieffry , You may need to update your code for the case where Centroid unit is not meters. Test file is attached.

• Member, Employee Posts: 312
edited December 2023
Options

@Pierre Thieffry @ZZ.tang ,
I think there are CAD imports that can effect the unit of the geometry. To get this unit for the geometry (GeoData) you can use this:

ExtAPI.DataModel.GeoData.Unit

https://discuss.ansys.com/discussion/2791

• Member, Employee Posts: 243
Options

Hmmm. I forgot about ExtAPI.DataModel.GeoData.Unit. Anyone know the difference between ExtAPI.DataModel.GeoData.Unit and ExtAPI.Graphics.Unit? In my testing, it seems that they are both always equal to Geometry > Definition > Length Unit

• Member, Employee Posts: 312
Options

@Landon Mitchell Kanner , I think the current setup in Mechanical is the Graphics unit will be the same as the CAD unit, but no guarantee this could not change in the future. The fact that each domain has the capacity for its own unit is robustness in the Mechanical API, and thus it would be best practice to obtain the unit in whichever domain you are working in and ensure consistency with others by way of built-in unit conversions.