Skip to main content
Question

Extracting transformation Matrix


Hi,

 

 

Looking to extract the transformation matrix information from an E57 pointcloud file. Is there a way to do this? I know the information can be found in FME Data Inspector.

 

 

 

Thanks

 

 

 

13 replies

ryanw
Contributor
Forum|alt.badge.img
  • Contributor
  • June 19, 2017
Has anyone sorted this out? You can see the information in the inspector but I cannot seem to expose it as an attribute.

 

 


mark2atsafe
Safer
Forum|alt.badge.img+44
ryanw wrote:
Has anyone sorted this out? You can see the information in the inspector but I cannot seem to expose it as an attribute.

 

 

I asked one of our point cloud developers and we'll see what they say.

 


scyphers
Participant
Forum|alt.badge.img+5
  • Participant
  • June 19, 2017

Hi @ryanw

It might be something along the line of forcing the RevIt feature attributes above the meta-attribute line.

 

Please see expose custom attrs from RevIt using the AttributeExposer and i think there is maybe traits you can express using GeomPropertyExposer or to scratch at some of these.

and lastly there alot of clever features hiding in PointCloudExpressionEvaluator / PointCloudPropertyExtractor see if you can force the component into an attribute using one of these .

-S


mark2atsafe
Safer
Forum|alt.badge.img+44
ryanw wrote:
Has anyone sorted this out? You can see the information in the inspector but I cannot seem to expose it as an attribute.

 

 

Looks like the answer is no. Sorry. All I can suggest is that you contact our support team (safe.com/support) and ask them to file an enhancement request. I don't see one already.

 

 


mark2atsafe
Safer
Forum|alt.badge.img+44
ryanw wrote:
Has anyone sorted this out? You can see the information in the inspector but I cannot seem to expose it as an attribute.

 

 

Additionally, please feel free to post this as an idea, to see if other users feel the same need. https://safe.com/ideas

 

 

The more votes your idea gets, the more likely it will be completed. As an alternative we would be more than happy to add this idea to the ideas exchange anonymously on your behalf.

 

 


ryanw
Contributor
Forum|alt.badge.img
  • Contributor
  • June 19, 2017
mark2atsafe wrote:
Additionally, please feel free to post this as an idea, to see if other users feel the same need. https://safe.com/ideas

 

 

The more votes your idea gets, the more likely it will be completed. As an alternative we would be more than happy to add this idea to the ideas exchange anonymously on your behalf.

 

 

Thanks Mark, I've implemented both of your suggestions.

 

 


takashi
Evangelist
  • June 20, 2017

The transformation matrix will be logged by the Logger, so I think you can extract the required information from the feature log if you sneak a peek at log.

0684Q00000ArLdWQAV.png

# PythonCaller Script
import fmeobjects

def collectLog(sevirity, message):
    g_logger.append(message)

class PreProcessor(object):
    def __init__(self):
        fmeobjects.FMELogFile().setCallBack(collectLog)
        
    def input(self,feature):
        global g_logger
        g_logger = []
        self.pyoutput(feature)

# PythonCaller_2 Script
class PostProcessor(object):
    def input(self, feature):
        feature.setAttribute("_log""\n".join(g_logger))
        self.pyoutput(feature)

The attribute named "_log" stores a text string like this. You can then parse this text to extract the transformation matrix.

Logger: Feature is:
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Feature Type: `Logger_LOGGED'
Attribute(string): `fme_basename' has value `PointCloudCreator'
Attribute(string): `fme_feature_type' has value `PointCloudCreator'
Attribute(string): `fme_geometry' has value `fme_polygon'
Attribute(string): `fme_type' has value `fme_point_cloud'
Coordinate System: `'
Geometry Type: IFMEPointCloud
Transformation Matrix:
   |0.86602540378443904 -0.49999999999999928 0 30|
   |0.49999999999999928 0.86602540378443904  0 50|
   |0                   0                    1 0 |
   |0                   0                    0 1 |
Global Extent Min: (-31.999999999999908,50,0)
Global Extent Max: (137.38715006927043,219.38715006927035,20)
Number of points: 15625
Components: 
   x (Real64)
   y (Real64)
   z (Real64)
===========================================================================

[Update] This script for the PythonCaller_2 extracts individual elements of the transformation matrix from the log and stores them as feature attributes.

# PythonCaller_2 Script [Update]
class PostProcessor(object):
    def input(self, feature):
        # Extract rows containing transformation matrix from the log.
        matrix, flag = [], False
        for r in [s.strip() for s in g_logger]:
            if not flag and r.startswith('Transformation Matrix:'):
                flag = True
            elif flag and len(matrix) < 4:
                matrix.append(r.strip('|'))
                
        # Extract every element of the matrix.
        if len(matrix) == 4:
            r = [s.split() for s in matrix]
            attrs = {
                "_A": r[0][0], "_B": r[0][1], "_C": r[0][2], "_D": r[0][3],
                "_E": r[1][0], "_F": r[1][1], "_G": r[1][2], "_H": r[1][3],
                "_I": r[2][0], "_J": r[2][1], "_K": r[2][2], "_L": r[2][3],
                "_M": r[3][0], "_N": r[3][1], "_O": r[3][2], "_P": r[3][3],
            }
            for k in attrs.keys():
                feature.setAttribute(k, float(attrs[k]))
                
        feature.setAttribute("_log""\n".join(g_logger)) # Optional
        feature.setAttribute("_matrix{}", matrix) # Optional
        
        self.pyoutput(feature)


ryanw
Contributor
Forum|alt.badge.img
  • Contributor
  • June 21, 2017
takashi wrote:

The transformation matrix will be logged by the Logger, so I think you can extract the required information from the feature log if you sneak a peek at log.

0684Q00000ArLdWQAV.png

# PythonCaller Script
import fmeobjects

def collectLog(sevirity, message):
    g_logger.append(message)

class PreProcessor(object):
    def __init__(self):
        fmeobjects.FMELogFile().setCallBack(collectLog)
        
    def input(self,feature):
        global g_logger
        g_logger = []
        self.pyoutput(feature)

# PythonCaller_2 Script
class PostProcessor(object):
    def input(self, feature):
        feature.setAttribute("_log""\n".join(g_logger))
        self.pyoutput(feature)

The attribute named "_log" stores a text string like this. You can then parse this text to extract the transformation matrix.

Logger: Feature is:
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Feature Type: `Logger_LOGGED'
Attribute(string): `fme_basename' has value `PointCloudCreator'
Attribute(string): `fme_feature_type' has value `PointCloudCreator'
Attribute(string): `fme_geometry' has value `fme_polygon'
Attribute(string): `fme_type' has value `fme_point_cloud'
Coordinate System: `'
Geometry Type: IFMEPointCloud
Transformation Matrix:
   |0.86602540378443904 -0.49999999999999928 0 30|
   |0.49999999999999928 0.86602540378443904  0 50|
   |0                   0                    1 0 |
   |0                   0                    0 1 |
Global Extent Min: (-31.999999999999908,50,0)
Global Extent Max: (137.38715006927043,219.38715006927035,20)
Number of points: 15625
Components: 
   x (Real64)
   y (Real64)
   z (Real64)
===========================================================================

[Update] This script for the PythonCaller_2 extracts individual elements of the transformation matrix from the log and stores them as feature attributes.

# PythonCaller_2 Script [Update]
class PostProcessor(object):
    def input(self, feature):
        # Extract rows containing transformation matrix from the log.
        matrix, flag = [], False
        for r in [s.strip() for s in g_logger]:
            if not flag and r.startswith('Transformation Matrix:'):
                flag = True
            elif flag and len(matrix) < 4:
                matrix.append(r.strip('|'))
                
        # Extract every element of the matrix.
        if len(matrix) == 4:
            r = [s.split() for s in matrix]
            attrs = {
                "_A": r[0][0], "_B": r[0][1], "_C": r[0][2], "_D": r[0][3],
                "_E": r[1][0], "_F": r[1][1], "_G": r[1][2], "_H": r[1][3],
                "_I": r[2][0], "_J": r[2][1], "_K": r[2][2], "_L": r[2][3],
                "_M": r[3][0], "_N": r[3][1], "_O": r[3][2], "_P": r[3][3],
            }
            for k in attrs.keys():
                feature.setAttribute(k, float(attrs[k]))
                
        feature.setAttribute("_log""\n".join(g_logger)) # Optional
        feature.setAttribute("_matrix{}", matrix) # Optional
        
        self.pyoutput(feature)

Thanks @takashi this is a viable workaround. Much appreciated. 


Forum|alt.badge.img

Hello !

In the log there is also a "Name(UTF-8):" attribute that can be interesting to extract in addition to the transformation matrix values.

log.PNG

I want to adapt your " PythonCaller_2 Script [Update] " to extract the "Name(UTF-8):" line but I don't know how to proceed ... If you eventually know which line(s) I need to add in the python script to extract the "Name(UTF-8):" you will save my week!

Kind regards,

Arnaud


Forum|alt.badge.img
takashi wrote:

The transformation matrix will be logged by the Logger, so I think you can extract the required information from the feature log if you sneak a peek at log.

0684Q00000ArLdWQAV.png

# PythonCaller Script
import fmeobjects

def collectLog(sevirity, message):
    g_logger.append(message)

class PreProcessor(object):
    def __init__(self):
        fmeobjects.FMELogFile().setCallBack(collectLog)
        
    def input(self,feature):
        global g_logger
        g_logger = []
        self.pyoutput(feature)

# PythonCaller_2 Script
class PostProcessor(object):
    def input(self, feature):
        feature.setAttribute("_log""\n".join(g_logger))
        self.pyoutput(feature)

The attribute named "_log" stores a text string like this. You can then parse this text to extract the transformation matrix.

Logger: Feature is:
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Feature Type: `Logger_LOGGED'
Attribute(string): `fme_basename' has value `PointCloudCreator'
Attribute(string): `fme_feature_type' has value `PointCloudCreator'
Attribute(string): `fme_geometry' has value `fme_polygon'
Attribute(string): `fme_type' has value `fme_point_cloud'
Coordinate System: `'
Geometry Type: IFMEPointCloud
Transformation Matrix:
   |0.86602540378443904 -0.49999999999999928 0 30|
   |0.49999999999999928 0.86602540378443904  0 50|
   |0                   0                    1 0 |
   |0                   0                    0 1 |
Global Extent Min: (-31.999999999999908,50,0)
Global Extent Max: (137.38715006927043,219.38715006927035,20)
Number of points: 15625
Components: 
   x (Real64)
   y (Real64)
   z (Real64)
===========================================================================

[Update] This script for the PythonCaller_2 extracts individual elements of the transformation matrix from the log and stores them as feature attributes.

# PythonCaller_2 Script [Update]
class PostProcessor(object):
    def input(self, feature):
        # Extract rows containing transformation matrix from the log.
        matrix, flag = [], False
        for r in [s.strip() for s in g_logger]:
            if not flag and r.startswith('Transformation Matrix:'):
                flag = True
            elif flag and len(matrix) < 4:
                matrix.append(r.strip('|'))
                
        # Extract every element of the matrix.
        if len(matrix) == 4:
            r = [s.split() for s in matrix]
            attrs = {
                "_A": r[0][0], "_B": r[0][1], "_C": r[0][2], "_D": r[0][3],
                "_E": r[1][0], "_F": r[1][1], "_G": r[1][2], "_H": r[1][3],
                "_I": r[2][0], "_J": r[2][1], "_K": r[2][2], "_L": r[2][3],
                "_M": r[3][0], "_N": r[3][1], "_O": r[3][2], "_P": r[3][3],
            }
            for k in attrs.keys():
                feature.setAttribute(k, float(attrs[k]))
                
        feature.setAttribute("_log""\n".join(g_logger)) # Optional
        feature.setAttribute("_matrix{}", matrix) # Optional
        
        self.pyoutput(feature)

Hello !

In the log there is also a "Name(UTF-8):" attribute that can be interesting to extract in addition to the transformation matrix values.

log.PNG

I want to adapt your " PythonCaller_2 Script [Update] " to extract the "Name(UTF-8):" line but I don't know how to proceed ... If you eventually know which line(s) I need to add in the python script to extract the "Name(UTF-8):" you will save my week!

Kind regards,

Arnaud


takashi
Evangelist
  • October 22, 2019
arnaudfouch wrote:

Hello !

In the log there is also a "Name(UTF-8):" attribute that can be interesting to extract in addition to the transformation matrix values.

log.PNG

I want to adapt your " PythonCaller_2 Script [Update] " to extract the "Name(UTF-8):" line but I don't know how to proceed ... If you eventually know which line(s) I need to add in the python script to extract the "Name(UTF-8):" you will save my week!

Kind regards,

Arnaud

It's the geometry name, and you can extract it as a feature attribute with the GeometryPropertyExtractor transformer. Don't need to use Python.


Forum|alt.badge.img
arnaudfouch wrote:

Hello !

In the log there is also a "Name(UTF-8):" attribute that can be interesting to extract in addition to the transformation matrix values.

log.PNG

I want to adapt your " PythonCaller_2 Script [Update] " to extract the "Name(UTF-8):" line but I don't know how to proceed ... If you eventually know which line(s) I need to add in the python script to extract the "Name(UTF-8):" you will save my week!

Kind regards,

Arnaud

@takashi Thanks a lot ! It work very well ! :)


virtualcitymatt
Celebrity
Forum|alt.badge.img+36

Just updating this post. I've created a CustomTansformer which can extract the transformation matrix from regular 3D objects (faces). https://hub.safe.com/publishers/vcs/transformers/transformationmatrixextractor

 

Unfortunately it doesn't yet support Point Clouds...so stuck with the logging solution from @Takashi Iijima​ 

 

Related is this one which applies and removes the transformation matrix: https://hub.safe.com/publishers/vcs/transformers/transformationmatrixremover

 


Cookie policy

We use cookies to enhance and personalize your experience. If you accept you agree to our full cookie policy. Learn more about our cookies.

 
Cookie settings