When a face is in a group,uv I get is wrong,why?

when a face in group,the uv I got is too large than actually uv。
I broken the group, the uv become right
SKP-UV-TEST.zip (1.2 MB)

this is how I try to get the uv:
API call:
SUModelCreateFromFileWithStatus
SUModelGetEntities
SUEntitiesGetGroups(for group)
SUGroupToEntity(for group)
SUEntitiesGetFaces
GetUVByFace

std::vector<SUPoint2D> GetUVByFace(const SUFaceRef face)
{
    std::vector<SUPoint2D> ret;

    const std::vector<SUPoint3D> VERTICES = GetFaceVertex(face);
    const int VERTICES_COUNT = VERTICES.size();
    // to get uv by SUTextureWriterGetFrontFaceUVCoords
    SUTextureWriterRef tWriter {nullptr};
    SU_CALL(SUTextureWriterCreate(&tWriter));
    std::vector<SUPoint2D> frontUVS(VERTICES_COUNT, {0,0});
    std::vector<SUPoint2D> backUVS(VERTICES_COUNT, {0,0});
    SUTextureWriterGetFrontFaceUVCoords(tWriter, face, VERTICES_COUNT, &VERTICES[0], &frontUVS[0]);
    SUTextureWriterGetBackFaceUVCoords(tWriter, face, VERTICES_COUNT, &VERTICES[0], &backUVS[0]);

    ret = frontUVS;

    // I also tried to get uv by SUUVHelperGetBackUVQ, but only got the same result;
    SUUVHelperRef uv_helper = SU_INVALID;
    SU_CALL(SUFaceGetUVHelper(face, true, true, tWriter, &uv_helper));
    std::vector<SUUVQ> uvqf(VERTICES_COUNT, { 0,0,0 });
    std::vector<SUUVQ> uvqb(VERTICES_COUNT, { 0,0,0 });
    for (size_t i = 0; i < VERTICES_COUNT; i++) {
        SUUVHelperGetFrontUVQ(uv_helper, &VERTICES[i], &uvqf[i]);
        SUUVHelperGetBackUVQ(uv_helper, &VERTICES[i], &uvqb[i]);
    }
	
    return ret;
}

the all source file is

#include <SketchUpAPI/common.h>
#include <SketchUpAPI/geometry.h>
#include <SketchUpAPI/initialize.h>
#include <SketchUpAPI/unicodestring.h>
#include <SketchUpAPI/model/model.h>
#include <SketchUpAPI/model/entities.h>
#include <SketchUpAPI/model/face.h>
#include <SketchUpAPI/model/edge.h>
#include <SketchUpAPI/model/vertex.h>
#include <SketchUpAPI/model/group.h>
#include <SketchUpAPI/model/texture.h>
#include <SketchUpAPI/model/texture_writer.h>
#include <SketchUpAPI/model/uv_helper.h>

#include <vector>
#include <iostream>
#include <queue>

std::vector<SUPoint3D> GetFaceVertex(SUFaceRef face) {
    std::vector<SUPoint3D> pts;

    size_t vtCount = 0;
    SUFaceGetNumVertices(face, &vtCount);
    if (vtCount > 0) {
        std::vector<SUVertexRef> vtRefs(vtCount);
        SUFaceGetVertices(face, vtCount, &vtRefs[0], &vtCount);
        pts = std::vector<SUPoint3D>(vtCount);
        for (size_t i = 0; i < vtCount; i++) {
            SUVertexGetPosition(vtRefs[i], &pts[i]);
        }
    }
    
    return pts;
}

std::vector<SUPoint2D> GetUVByFace(const SUFaceRef face)
{
    std::vector<SUPoint2D> ret;

    const std::vector<SUPoint3D> VERTICES = GetFaceVertex(face);
    const int VERTICES_COUNT = VERTICES.size();
    // to get uv by SUTextureWriterGetFrontFaceUVCoords
    SUTextureWriterRef tWriter{ nullptr };
    SUTextureWriterCreate(&tWriter);
    std::vector<SUPoint2D> frontUVS(VERTICES_COUNT, { 0,0 });
    std::vector<SUPoint2D> backUVS(VERTICES_COUNT, { 0,0 });
    SUTextureWriterGetFrontFaceUVCoords(tWriter, face, VERTICES_COUNT, &VERTICES[0], &frontUVS[0]);
    SUTextureWriterGetBackFaceUVCoords(tWriter, face, VERTICES_COUNT, &VERTICES[0], &backUVS[0]);

    ret = frontUVS;

    // TEST - I also tried to get uv by SUUVHelperGetBackUVQ, but only got the same result;
    {
        SUUVHelperRef uv_helper = SU_INVALID;
        SUFaceGetUVHelper(face, true, true, tWriter, &uv_helper);
        std::vector<SUUVQ> uvqf(VERTICES_COUNT, { 0,0,0 });
        std::vector<SUUVQ> uvqb(VERTICES_COUNT, { 0,0,0 });
        for (size_t i = 0; i < VERTICES_COUNT; i++) {
            SUUVHelperGetFrontUVQ(uv_helper, &VERTICES[i], &uvqf[i]);
            SUUVHelperGetBackUVQ(uv_helper, &VERTICES[i], &uvqb[i]);
        }
    }

    return ret;
}

int main() {
  // Always initialize the API before using it
  SUInitialize();

  // Load the model from a file
  SUModelRef model = SU_INVALID;
  SUModelLoadStatus status;
  SUResult res = SUModelCreateFromFileWithStatus(&model, 
      R"(.\SKP-UV-TEST\uv-error-grass-inGroup.skp)",
      &status);

  // It's best to always check the return code from each SU function call.
  // Only showing this check once to keep this example short.
  if (res != SU_ERROR_NONE) {
    std::cout << "Failed creating model from a file" << std::endl;
    return 1;
  }

  if (status == SUModelLoadStatus_Success_MoreRecent) {
    std::cout
        << "This model was created in a more recent SketchUp version than that of the SDK. "
           "It contains data which will not be read. Saving the model over the original file may "
           "lead to permanent data loss."
        << std::endl;
  }

  // Get the entity container of the model.
  SUEntitiesRef entities = SU_INVALID;
  SUModelGetEntities(model, &entities);

  // bfs :: ergodic all group to deal with faces
  std::queue<SUEntitiesRef> bfsEntitiesQueue({ entities });
  while (bfsEntitiesQueue.empty() == false)
  {
      SUEntitiesRef entitiesRef = bfsEntitiesQueue.front();
      bfsEntitiesQueue.pop();

      // push sub group entities to bfs
      size_t groupsCount = 0;
      SUEntitiesGetNumGroups(entitiesRef, &groupsCount);
      if (groupsCount > 0) {
          std::vector<SUGroupRef> groups(groupsCount);
          SUEntitiesGetGroups(entitiesRef, groupsCount, &groups[0], &groupsCount);
          for (size_t i = 0; i < groups.size(); i++) {
              SUGroupRef group = groups[i];
              SUEntitiesRef groupEntities;
              SUGroupGetEntities(group, &groupEntities);
              bfsEntitiesQueue.push(groupEntities);
              
          }
      }

      // deal faces
      size_t facesCount = 0;
      SUEntitiesGetNumFaces(entitiesRef, &facesCount);
      if (facesCount > 0) {
          std::vector<SUFaceRef> faces(facesCount);
          SUEntitiesGetFaces(entitiesRef, facesCount, &faces[0], &facesCount);
          for (size_t i = 0; i < faces.size(); i++)
          {
              SUFaceRef face = faces[i];
              // TODO -- get and check uv。I found that the uv is error
              std::vector<SUPoint2D> uvs = GetUVByFace(face);
              continue;
          }
      }
  }
  return 0;
}

Please post code correctly in the forum …

Does this bug report explain your issue?

It seems not,is there any other idea about it? greatly appreciate~

I have post the function code about how i try to get uv;
and the source file about my demo to deal with the file in the zip “SKP-UV-TEST.zip”
help please

Because the material is assigned on the group level, you’ll probably need to divide uvs by texture scale:

SUGroupToDrawingElement()
SUDrawingElementGetMaterial()
SUMaterialGetTexture()
SUTextureGetDimensions(texture_ref, &texture_width, &texture_height, &texture_scale_u, &texture_scale_v)

u = uvs[i].x / (texture_scale_u * uvs[i].z);
v = uvs[i].y / (texture_scale_v * uvs[i].z);

thank you for the help,I’ve solved the problem by it