The SketchUp C API sample I’m using demonstrates how to read SketchUp files, but I’m not sure how to load the face indices from the associated model.
The code following does works but it just affects the vertex data.
Please check the code below to assist with loading the face indices from the sample code.
#include <slapi/slapi.h> #include <slapi/geometry.h> #include <slapi/initialize.h> #include <slapi/unicodestring.h> #include <slapi/model/model.h> #include <slapi/model/entities.h> #include <slapi/model/face.h> #include <slapi/model/edge.h> #include <slapi/model/vertex.h> #include
int main() {
// Always initialize the API before using it
SUInitialize();
// Load the model from a file
SUModelRef model = SU_INVALID;
SUResult res = SUModelCreateFromFile(&model, “model.skp”);
// 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)
return 1;
// Get the entity container of the model.
SUEntitiesRef entities = SU_INVALID;
SUModelGetEntities(model, &entities);
// Get all the faces from the entities object
size_t faceCount = 0;
SUEntitiesGetNumFaces(entities, &faceCount);
if (faceCount > 0) {
std::vector faces(faceCount);
SUEntitiesGetFaces(entities, faceCount, &faces[0], &faceCount);
// Get all the edges in this face
for (size_t i = 0; i < faceCount; i++) {
size_t edgeCount = 0;
SUFaceGetNumEdges(faces[i], &edgeCount);
if (edgeCount > 0) {
std::vector edges(edgeCount);
SUFaceGetEdges(faces[i], edgeCount, &edges[0], &edgeCount);
// Get the vertex positions for each edge
for (size_t j = 0; j < edgeCount; j++) {
SUVertexRef startVertex = SU_INVALID;
SUVertexRef endVertex = SU_INVALID;
SUEdgeGetStartVertex(edges[j], &startVertex);
SUEdgeGetEndVertex(edges[j], &endVertex);
SUPoint3D start;
SUPoint3D end;
SUVertexGetPosition(startVertex, &start);
SUVertexGetPosition(endVertex, &end);
// Now do something with the point data
}
}
}
}
// Get model name
SUStringRef name = SU_INVALID;
SUStringCreate(&name);
SUModelGetName(model, &name);
size_t name_length = 0;
SUStringGetUTF8Length(name, &name_length);
char* name_utf8 = new char[name_length + 1];
SUStringGetUTF8(name, name_length + 1, name_utf8, &name_length);
// Now we have the name in a form we can use
SUStringRelease(&name);
delete name_utf8;
// Must release the model or there will be memory leaks
SUModelRelease(&model);
// Always terminate the API when done using it
SUTerminate();
return 0;
}
Here what I tried so far.
From where can I get the total part/assembly count. I need to fill the data part wise.
Here I am getting triangles for all the parts. How can I get this partwise?
SUInitialize();
Part partData;
Face faceData;
Assembly assembly;
partData.partName = "PartCube";
partData.m_isVisible = true;
size_t EntityCount = 0;
// Load the model from a file
SUModelRef model = SU_INVALID;
SUModelLoadStatus status;
SUResult res = SUModelCreateFromFileWithStatus(&model, path, &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;
}
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);
SUEntityListRef list = SU_INVALID;
// Get all the faces from the entities object
size_t faceCount = 0;
SUEntitiesGetNumFaces(entities, &faceCount);
std::cout << "Number of faces: " << faceCount << std::endl;
if (faceCount > 0)
{
std::vector<SUFaceRef> faces(faceCount);
SUEntitiesGetFaces(entities, faceCount, &faces[0], &faceCount);
for (size_t i = 0; i < faceCount; i++)
{
std::vector<double> vertexCoordinate;
std::vector<double> normalCoordinate;
std::vector<int> faceindices;
SUFaceRef faceRef = faces[i];
// Load face geometry.
SUMeshHelperRef polyMesh = SU_INVALID;
SUMeshHelperCreate(&polyMesh, faceRef);
size_t numberOfVertices = 0;
size_t numberOfIndices = 0;
size_t numberOfNormals = 0;
size_t result = 0;
if (SUIsValid(polyMesh))
{
SUMeshHelperGetNumVertices(polyMesh, &numberOfVertices);
std::vector<SUPoint3D> points(numberOfVertices);
std::vector<SUPoint3D> uvs(numberOfVertices);
std::vector<SUPoint3D> backUvs(numberOfVertices);
std::vector<SUVector3D> normals(numberOfVertices);
// Get data from polyMesh
SUMeshHelperGetVertices(polyMesh, numberOfVertices, &points[0], &result);
SUMeshHelperGetNormals(polyMesh, numberOfNormals, &normals[0], &result);
numberOfNormals = result;
SUMeshHelperGetFrontSTQCoords(polyMesh, numberOfVertices, &uvs[0], &result);
SUMeshHelperGetBackSTQCoords(polyMesh, numberOfVertices, &backUvs[0], &result);
// Load indices.
SUMeshHelperGetNumTriangles(polyMesh, &numberOfIndices);
numberOfIndices = numberOfIndices * 3;
std::vector<size_t> indices(numberOfIndices);
SUMeshHelperGetVertexIndices(polyMesh, numberOfIndices, &indices[0], &result);
for (int i = 0; i < numberOfVertices; i++)
{
vertexCoordinate.push_back(points[i].x);
vertexCoordinate.push_back(points[i].y);
vertexCoordinate.push_back(points[i].z);
normalCoordinate.push_back(normals[i].x);
normalCoordinate.push_back(normals[i].y);
normalCoordinate.push_back(normals[i].z);
}
for (const auto& index : indices)
{
faceindices.push_back(static_cast<int>(index));
}
// Release polyMesh helper
SUMeshHelperRelease(&polyMesh);
faceData.coordinates = vertexCoordinate;
faceData.indices = faceindices;
}
partData.faces.push_back(faceData);
faceData.faceColor.red = 160;
faceData.faceColor.green = 160;
faceData.faceColor.blue = 160;
faceData.faceColor.opacity = 255;
}
}
assembly.parts.push_back(partData);
assembly.assemblyName = "Cube";
assembly.m_isVisible = true;
// Get model name
SUStringRef name = SU_INVALID;
SUStringCreate(&name);
SUModelGetName(model, &name);
size_t name_length = 0;
SUStringGetUTF8Length(name, &name_length);
char* name_utf8 = new char[name_length + 1];
SUStringGetUTF8(name, name_length + 1, name_utf8, &name_length);
// Now we have the name in a form we can use
SUStringRelease(&name);
delete[] name_utf8;
// Must release the model or there will be memory leaks
SUResult result = SUModelRelease(&model);
if (result != SU_ERROR_NONE)
{
std::cout << "Reading SketchUp model: Failed" << std::endl;
}
else
{
std::cout << "Reading SketchUp model: Success" << std::endl;
}
// Always terminate the API when done using it
SUTerminate();
You need to learn more about SU scene structure and API.
The simplest way is to play a bit with Ruby API under SketchUp Ruby Console.
The above code can export only a ‘raw’ faces from the ‘root level’.
For components and groups you’ll need to get them from root level entities, and traverse whole scene tree to collect all faces from all instances/groups of all branches of the scene tree.
To get additional information you’ll need to cast object to SUDrawingElementRef(to get visibility, materials, layer info etc) or to SUEntityRef(to get object name, attributes etc).