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;texture.zip (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.
@return
- \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.
//test
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:
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?
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.
If I always load face into texture write, is there performance or capacity issue?