How to map STQ to ST?

Hi Experts,

SketchUp use UVQ mapping, which allow for perspective distortion of textures. However, my applications doesn’t support UVQ and instead require only UV.

tt_su suggested me to get UV from UVQ by:

u = u / q
v = v / q
q = 1.0

Now I have sketchup model with distortion of textures. Its texture file in disk is like that:

The model with the distortion of texture in SketchUp application will be like that:

After mapping UVQ into UV, it looks like that in my application:

You will find the texture in my application is not as good as in SketchUp application. I am calling the skp function “SUMeshHelperGetFrontSTQCoords()” to get STQ value; then get the ST by
S = S/Q;
T = T/Q;
Q = 1.0;

Could you please take a look at the issue? The model is attached.
1.skp (284.2 KB)


Yes - that’s because STQ is for projection mapping - when converting to ST by dividing by Q you lose that, you get a linear distortion instead. (Sorry, I should have been clearer about that.)
If your target format doesn’t support projective mapping (the Q value), then you either need to live with the visual deviance, or you need to use the SUTextureWriter and accept that new unique textures will be created for such faces.

@tt_su “You need to use the SUTextureWriter and accept that new unique textures will be created for such faces.”

Could you please explain it in detail? How to create a new unique texture for such faces? You know, I only have original image file just like the first picture in first post.


If you use the SUTextureWriter to write out textures it will create unique textures for faces with non-affine texture mappings. The exporter examples in the SDK package demonstrates how this is done.


I still don’t know how to create a new unique texture for such faces with non-affine texture mapping. I reviewed all functions in the files texture.h and texture_writer.h; (4.3 KB)

I didn’t see any functions to help me create a new unique texture for faces. You know, I don’t have the new texture file which is extracted from original texture file as below or new buffer data to create the new texture;

and only have original texture file as below and original buffer data.

Could you please figure out how to do with the detailed steps? I really appreciate for your help.


You load the faces into the texture writer using SUTextureWriterLoadFace - then when you use SUTextureWriterWriteAllTextures or SUTextureWriterWriteTexture it should generate a new unique texture for faces with non-affine mapping. Use the same SUTextureWriterRef for the functions to extract UV data in order to get correct UV data for the textures made unique.

Have you looked at the XML exporter in the samples folder of the SLAPI package? It should demonstrate the use of the TextureWriter.


I looked at the xml exporter in the samples folder. Yesterday I wrote some test codes as you suggested. The function SUTextureWriterWriteTexture() needs a texture_id. Yesterday I can’t find a function to get texture id of texture on face. Now I can get the texture id by loading face into texture write by calling the following function: SUTextureWriterLoadFace().

It seems that the comments of the function SUTextureWriterLoadFace() are wrong; the third and forth parameter should be out parameters; not in parameters.

@brief  Loads a face object to a texture writer object in order to have its
        front and/or back texture written to local disk.
@param[in] writer           The texture writer object.
@param[in] face             The face object.
@param[in] front_texture_id The texture ID of the front texture.
@param[in] back_texture_id  The texture ID of the back texture.
- \ref SU_ERROR_NONE on success
- \ref SU_ERROR_INVALID_INPUT if writer or face is not a valid object
- \ref SU_ERROR_NULL_POINTER_OUTPUT if the face object has a front face texture
  to write, and front_texture_id is NULL
- \ref SU_ERROR_NULL_POINTER_OUTPUT if the face object has a back face texture
  to write, and back_texture_id is NULL
- \ref SU_ERROR_GENERIC if the face object does not a texture to write
SU_RESULT SUTextureWriterLoadFace(SUTextureWriterRef writer,
                                  SUFaceRef face,
                                  long* front_texture_id,
                                  long* back_texture_id);

Then now I can generate a new texture after thinking the third/forth parameters as out parameters.
Here are my test codes.

SUTextureRef texture = SU_INVALID;
SUResult result = SUFaceGetFrontMaterial(m_skpface, &material); 
if(SU_ERROR_NONE == SUMaterialGetTexture(material, &texture))
    size_t count(0);
    SUTextureWriterGetNumTextures(texture_writer, &count);

    long frontId(0), backId(0);
    result = SUTextureWriterLoadFace(texture_writer, m_skpface, &frontId, &backId);

    SUTextureWriterGetNumTextures(texture_writer, &count);

    long textureId = 0;
    result = SUTextureWriterGetTextureIdForFace(texture_writer, m_skpface, bFrontMaterial, &textureId);

    bool bIsAffine = false;
    result = SUTextureWriterIsTextureAffine(texture_writer, textureId, &bIsAffine);

    const char* path = "c:\\phenix.png";
    result = SUTextureWriterWriteTexture(texture_writer, textureId, path, false);

//end test

Now my questions are:

  1. I don’t want to always generate a new texture when texture is not with distortion texture. Can I use the function SUTextureWriterIsTextureAffine() to check if a texture is a distortion texture?
  2. Whether or not there is other functions to get the texture id because i don’t want to get the texture id by the function “SUTextureWriterLoadFace()” because it always loads faces into texture writer.
  3. If I always load face into texture write, is there performance or capacity issue?

At last, thanks a lot for your support.


You are correct - this is a typo. I’l filing an issue for this to have it fixed. Thanks for your report.

TextureWriter shouldn’t create new textures if the mapping is affine. Are you seeing that it does?

The texture id relates to the ids of the TextureWriters loaded textures. It has to some from that.

Creating new textures will have some performance overhead. Exactly how much I cannot tell - I don’t have any good general numbers on that.

Yes. Now I am calling SUTextureWriterIsTextureAffine() to decide if generate a new texture.

Hm… Can you provide a small snippet and sample model?