How can I convert coordinates from global to local CS in Mechanical?
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?
Answers
-
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))
0 -
-
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:
0 -
I believe .Centroid uses this unit:
ExtAPI.Graphics.Unit
0 -
@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?
0 -
@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")
0 -
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.
1 -
@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
0 -
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
0 -
@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.
1