Model files are now saved in LPS coordinate system

While Slicer uses RAS coordinate system internally, images, transforms, and markups files are stored in LPS coordinate system, because DICOM and all medical image computing software (maybe except a few very old ones) uses LPS coordinate system in files.

However, Slicer has been still using its internal RAS coordinate system in mesh files (STL, VTK, VTP, OBJ, PLY), which caused issues when interfacing with third-party software.

Starting from tomorrow (Slicer-4.11.0-2020-02-26, revision 28794), Slicer Preview Release will save models in LPS coordinate system, and assume mesh files to be in LPS coordinate system by default.

Slicer started embedding coordinate system name in mesh files a few years ago (see SPACE=RAS in the file header), so all the files that Slicer saved in recent years will load correctly and any scene files created with any version of Slicer will also load the models with correct orientation, too.

Manual setting of coordinate system (in Add data dialog / Options column) is only needed when loading a mesh file without a scene that were created by Slicer-4.6 (2017-09-27) and earlier; and obj files created by Slicer-4.6 and Slicer-4.8 (between 2016-10-11 and 2018-03-26), or files are created by third-party software in RAS coordinate system.

See more details and list of modified files in this commit.

solid 3D Slicer output. SPACE=LPS
facet normal 0.670457 -0.150029 0.726621
outer loop
vertex 86.7619 22.6655 32.2962
vertex 85.9753 22.2651 32.9394

If you encounter orientation issues when loading a model file, you have the following options:

  • Option A: Specify the coordinate system when you open the model file. In “Add data” dialog, click “Show Options” and then choose “RAS” as coordinate system.

  • Option B: Update the third-party software that generate the mesh to save coordinates in LPS coordinate system instead of RAS coordinate system. Conversion is simple inverting the sign of the first two coordinates.

  • Option C: Write “SPACE=RAS” in the comment/description field in the mesh file (for STL, OBJ, PLY, VTK file; for VTP files, add in the first value of a vtkStringArray field array named “SPACE”) to indicate that the values are stored in RAS coordinate system. This option is useful if coordinates have to be stored in RAS coordinate system (for example, for compatibility with other software).

Examples of file headers that specify what coordinate system is used (click on the arrow on the left to expand)

Example of an STL file header that stores coordinates in RAS coordinate system:

solid 3D Slicer output. SPACE=RAS
 facet normal 0.670457 -0.150029 0.726621
  outer loop
   vertex 86.7619 22.6655 32.2962
   vertex 85.9753 22.2651 32.9394
...

Example of an OBJ file header that stores coordinates in RAS coordinate system:

# 3D Slicer output. SPACE=RAS

mtllib Segment_1.mtl

v 83.3949 8.0714 -7.2143
v 83.3949 9.0714 -7.2143
v 83.3949 10.0714 -7.2143
...

Example of a VTK file header that stores coordinates in RAS coordinate system:

# vtk DataFile Version 4.2
3D Slicer output. SPACE=RAS
BINARY
DATASET POLYDATA
POINTS 7192 float 
...

Example of a PLY file header that stores coordinates in RAS coordinate system:

ply
format binary_little_endian 1.0
comment VTK generated PLY File
comment SPACE=RAS
obj_info vtkPolyData points and polygons: vtk4.0
element vertex 13327
property float x
property float y
...

Example of a VTP file header that stores coordinates in RAS coordinate system:

<?xml version="1.0"?>
<VTKFile type="PolyData" version="0.1" byte_order="LittleEndian" header_type="UInt32">
  <PolyData>
    <FieldData>
      <Array type="String" Name="SPACE" NumberOfTuples="1" format="ascii">
        82 65 83 0
      </Array>
    </FieldData>
    <Piece NumberOfPoints="13327" NumberOfVerts="0" NumberOfLines="0" NumberOfStrips="0" NumberOfPolys="26650">
      <PointData>
...

See C++ code examples of writing coordinate system information when saving a mesh file here.

4 Likes

Will Slicer convert to using LPS internally at some point? It seems as though it would make sense given how many other applications use LPS.

Compatibility with other applications is taken care of by using LPS in files. It would make things simpler to switch to LPS internally, too. It is just a matter of development priorities. There are other things that would make bigger impact for Slicer developers (such as switching to VTK oriented image data) and users (better widgets, measurements, 4D support, etc.).

1 Like

@lassoan Hi Andras, the link at the end seems that it is unavailable. Could you please provide that since I am trying to find a way to read/write files in different spaces using python? Thanks a lot.

I’ve udpated the link. If you want to load an STL/OBJ/PLY/VTK/VTU file that does not have embedded cordinate system information in it and is stored in RAS coordinate system then you can load it like this:

modelNode = slicer.modules.models.logic().AddModel(
  "something.stl", slicer.vtkMRMLStorageNode.CoordinateSystemRAS)
1 Like

Good to know, I was having some problems recently related to this. It would be nice if this option is also available for markups.

1 Like

Yes, the same automatic LPS/RAS coordinate system switch is available for markups, too.

1 Like