Skip to main content

Hi all,

I’m trying to extract 3D data from a
3DCityDB (PostgreSQL) and write them into a sketchup file.

I have no problem handling the surfaces
and writing them into the .skp file as buildings.

But I have an issue with the textures. I
manage to get the right images on the right surfaces but they are not in
the right place.

I get the texture coordinates in a
field, and they are stored as below (u,v coordinates list) :

 

But I don't know what to do with these
coordinates... And how ta handle them with TextureCoordinateSetter... Any ideas ?

The idea would be to create a custom
reader for the 3DCityDB format and a workbench to extract data from the DB in
sktechup, multipatch,… It’s already done without the textures, but it would be
great (and usefull) to get the textures right.

Thank you in advance,

Fabien Laganne

Hi @flaganne, the texture coordinates (u, v) are coordinates which are regulated in the range of left-bottom (0,0) and right-upper (1,1) of the texture image. In an FME data translation process, texture coordinates are stored by the surface geometry as its measures called "fme_texture_coordinate_u", "fme_texture_coordinate_v", etc. See here to learn more: Texture Coordinates

If the input 3D Polygon feature has two list attributes that contain u-coordinates and v-coordinates separately, you can map the coordinates as the two measures - "fme_texture_coordinate_u" and "fme_texture_coordinate_v" to the Polygon (MeasureSetter x 2), replace it with a Surface (FaceReplacer), and then set a raster image as a texture to the surface (AppearanceSetter).

In your case, firstly you will have to convert the TEXTURE_COORDINATES (space-separated texture coordinates list) to two list attributes, which contain u-coordinates and v-coordinates separately.

See this workspace example that describes how you can set texture coordinates to a surface based on the given TEXTURE_COORDINATES. And also check the measures of resulting surface with FME Data Inspector (Feature Information Window).

texture-coordinate-mapping-example.fmw (FME 2017.0.1.1)

 

I don't know how the TextureCoordinateSetter transformer works...


Hi @flaganne, the texture coordinates (u, v) are coordinates which are regulated in the range of left-bottom (0,0) and right-upper (1,1) of the texture image. In an FME data translation process, texture coordinates are stored by the surface geometry as its measures called "fme_texture_coordinate_u", "fme_texture_coordinate_v", etc. See here to learn more: Texture Coordinates

If the input 3D Polygon feature has two list attributes that contain u-coordinates and v-coordinates separately, you can map the coordinates as the two measures - "fme_texture_coordinate_u" and "fme_texture_coordinate_v" to the Polygon (MeasureSetter x 2), replace it with a Surface (FaceReplacer), and then set a raster image as a texture to the surface (AppearanceSetter).

In your case, firstly you will have to convert the TEXTURE_COORDINATES (space-separated texture coordinates list) to two list attributes, which contain u-coordinates and v-coordinates separately.

See this workspace example that describes how you can set texture coordinates to a surface based on the given TEXTURE_COORDINATES. And also check the measures of resulting surface with FME Data Inspector (Feature Information Window).

texture-coordinate-mapping-example.fmw (FME 2017.0.1.1)

 

I don't know how the TextureCoordinateSetter transformer works...

If you were familiar with Python scripting, most transformers could be replaced with a PythonCaller.

 

# PythonCaller Script Example
# Sets texture coordinates given as an attribute value (space-separated u, v values)
# to an FMEPolygon geometry, and then replaces it with an FMEFace geometry.
# Assuming the input feature always has an FMEPolygon whose boundary is an FMELine,
# and the number of its vertices is consistent with the number of texture coordinates.
from fmeobjects import FMEFace, FMEPolygon, FME_CLOSE_3D_AVERAGE_MODE
def convertPolygonToFaceWithTextureCoordinates(feature):
    s = feature.getAttribute('TEXTURE_COORDINATES').split()
    u =  float(sti]) for i in range(0, len(s), 2)]
    v = Âfloat(sei]) for i in range(1, len(s), 2)]
    boundary = feature.getGeometry().getBoundaryAsCurve()
    boundary.setMeasure(u, 'fme_texture_coordinate_u')
    boundary.setMeasure(v, 'fme_texture_coordinate_v')
    feature.setGeometry(FMEFace(FMEPolygon(boundary), FME_CLOSE_3D_AVERAGE_MODE))

0684Q00000ArMbWQAV.png

 

It seems that the TextureCoordinateSetter just modifies the existing texture coordinates stored as measures of a surface according to the parameters and won't set new texture coordinates to the surface.

@takashi Thank you for these 2 solutions! I gonna try today and will keep you updated.

 


Hi @flaganne, the texture coordinates (u, v) are coordinates which are regulated in the range of left-bottom (0,0) and right-upper (1,1) of the texture image. In an FME data translation process, texture coordinates are stored by the surface geometry as its measures called "fme_texture_coordinate_u", "fme_texture_coordinate_v", etc. See here to learn more: Texture Coordinates

If the input 3D Polygon feature has two list attributes that contain u-coordinates and v-coordinates separately, you can map the coordinates as the two measures - "fme_texture_coordinate_u" and "fme_texture_coordinate_v" to the Polygon (MeasureSetter x 2), replace it with a Surface (FaceReplacer), and then set a raster image as a texture to the surface (AppearanceSetter).

In your case, firstly you will have to convert the TEXTURE_COORDINATES (space-separated texture coordinates list) to two list attributes, which contain u-coordinates and v-coordinates separately.

See this workspace example that describes how you can set texture coordinates to a surface based on the given TEXTURE_COORDINATES. And also check the measures of resulting surface with FME Data Inspector (Feature Information Window).

texture-coordinate-mapping-example.fmw (FME 2017.0.1.1)

 

I don't know how the TextureCoordinateSetter transformer works...

Another way with the FME powerful string operations.

 


Thanks a lot @takashi, I used the first solution, and it works perfectly !!


Another way with the FME powerful string operations.

 

The second StringSearcher can be set more simply, like this.

 

  • Search In: @Value(TEXTURE_COORDINATES)
  • Contains Regular Expression: \\S+\\s+(\\S+)\\s*
  • Subexpression Matches List Name: _v

 


Reply