Same material different texture?

Hello, I am trying to parse the faces of the entity as shown in the figure. It appears that all the faces share the same material, but their texture IDs are different. Also, it seems that the SDK has created a small texture cropped from the original texture for every single face. Is there any way I can make all the faces sharing the same texture and obtain the corresponding UV coordinates?

SketchUp uses projection mapping (UVQ), check this thread:

SUTextureWriter can generate unique textures with mapping applied (this is the reason why you have a bunch of tiny textures).
Check: SUTextureWriterIsTextureAffine
AFAIR you can’t disable this.

If you don’t need this functionality, you’ll need to export textures straight from materials.

Thanks, If I export textures straight from materials, how to separately export the front and back material of a face? And how can I export the texture coordinates corresponding to the overall texture?

To get STQ from faces:

SUMeshHelperCreate
SUMeshHelperGetFrontSTQCoords
SUMeshHelperGetBackSTQCoords

Don’t forget to release mesh helper:
SUMeshHelperRelease

To get materials from face:

SUFaceGetFrontMaterial
SUFaceGetBackMaterial

Keep in mind, that the material may be derived from object (component) parent, you can get it by SUDrawingElementGetMaterial

If SUFaceGetFrontMaterial / SUFaceGetBackMaterial return SU_ERROR_NONE, there is no material at this level, but may be derived from parent object.

If the material contains texture, you’ll need to get scaleU/scaleV from texture:
SUTextureGetDimensions and maybe (this depends from yours solution) multiply this by UV that you got from MeshHelper.

1 Like

Thank you for your reply.
Actually, I want to apply only one texture for a whole face (with non_affine texture mapping) in order to accelerate rendering, in stead of generating tiny texture for every tessellated triangle by SUTextureWriter,do you have any advice? or do I have to merge all tiny textures myself?

The above solution should be good for you (we’re using the same):

  • compute material for face (get it from face or from the parent object),
  • get texture from material (there will be only one texture),
  • get texture scaleU/scaleV
  • create MeshHelper for face,
  • extract FrontSTQ and multiply them by texture scaleU/scaleV
  • you can also simulate a bit correction by multiplying S/Q and T/Q (as mentioned in the article attached above)


I have tried to get the texture right from material but it seems to get the wrong mapping.

Could you share the skp file?

test.skp (8.2 MB)
The model is attached.

Works as expected:
Looks like you didn’t applied the texture scale to the UVs

SUMaterialRef frontMaterial = SU_INVALID;
SUMaterialRef backMaterial = SU_INVALID;

SUFaceGetFrontMaterial(faceRef, &frontMaterial);
SUFaceGetBackMaterial(faceRef, &backMaterial);

SUTextureRef frontTextureRef= SU_INVALID;
SUTextureRef backTextureRef= SU_INVALID;

SUMaterialGetTexture(frontMaterial, &frontTextureRef);
SUMaterialGetTexture(backMaterial, &backTextureRef);

size_t txWidth = 1, txHeight = 1;
double divFrontU = 1.0, divFrontV = 1.0;
double divBackU = 1.0, divBackV = 1.0;
SUTextureGetDimensions(frontTextureRef, &txWidth, &txHeight, &divFrontU, &divFrontV);
SUTextureGetDimensions(backTextureRef, &txWidth, &txHeight, &divBackU, &divBackV);

SUMeshHelperRef polyMesh = SU_INVALID;
SUMeshHelperCreate(&polyMesh, faceRef);

size_t result;
size_t numberOfVertices = 0;

SUMeshHelperGetNumVertices(polyMesh, &numberOfVertices);

std::vector<SUPoint3D> uvs(numberOfVertices);
std::vector<SUPoint3D> backUvs(numberOfVertices);

SUMeshHelperGetFrontSTQCoords(polyMesh, numberOfVertices, &uvs[0], &result);
SUMeshHelperGetBackSTQCoords(polyMesh, numberOfVertices, &backUvs[0], &result);

for (int i = 0; i < numberOfVertices; i++)
{
	size_t pos = i;
	double q = uvs[pos].z;
	double bq = backUvs[pos].z;

	faceData->uvs.push_back((float)(uvs[pos].x / (divFrontU * q)));
	faceData->uvs.push_back((float)(uvs[pos].y / (divFrontV * q)));

	faceData->backUvs.push_back((float)(backUvs[pos].x / (divBackU * bq)));
	faceData->backUvs.push_back((float)(backUvs[pos].y / (divBackV * bq)));
}

SUMeshHelperRelease(&polyMesh);

The code is simplified, no error checking etc.