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;
}