Skip to content

Instantly share code, notes, and snippets.

@jimfoltz
Last active July 4, 2022 07:51
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save jimfoltz/0644d189146b4db373903ff59bbef7a9 to your computer and use it in GitHub Desktop.
Save jimfoltz/0644d189146b4db373903ff59bbef7a9 to your computer and use it in GitHub Desktop.
convert mesh files to .skp using assimp library
#include <SketchUpAPI/SketchUp.h>
#include <iostream>
#include <assimp/Importer.hpp>
#include <assimp/scene.h>
#include <assimp/postprocess.h>
#include <assimp/DefaultLogger.hpp>
#include "output_sketchup_error.h"
// #define SU_CALL(func) if ((func) != SU_ERROR_NONE) throw std::exception()
// Quick debugging
#define CHECK(r) if (r != SU_ERROR_NONE) { \
std::cout << "SU Error line: " << __LINE__ << "\n"; \
output_sketchup_error(r); return 1; }
int main(int argc, char *argv[]) {
if (argc < 2)
{
std::cout << "Usage: " << argv[0] << " file\n";
return 1;
}
//const double Scale{ 39.3701 };
const double Scale{ 1000.0 };
// Log to STDERR in this case
//Assimp::DefaultLogger::create("", Assimp::Logger::VERBOSE, aiDefaultLogStream_STDERR);
Assimp::Importer importer;
// std::string exts = "";
// importer.GetExtensionList(exts);
// std::cout << exts << std::endl;
std::string filename = argv[1];
std::string logname = filename + ".log";
Assimp::DefaultLogger::create(logname.c_str());
const aiScene *scene = importer.ReadFile(
filename,
aiProcess_JoinIdenticalVertices |
aiProcess_Triangulate |
aiProcess_ValidateDataStructure |
aiProcess_PreTransformVertices |
0
);
if (!scene)
{
std::cout << "An error occured: " << importer.GetErrorString() << "\n";
return 1;
}
// Setup the SketchUp API data structures.
// Always initialize the API before using it
SUInitialize();
// Create the model
SUModelRef model = SU_INVALID;
SUResult res = SUModelCreate(&model);
CHECK(res);
// Get the entity container of the model
SUEntitiesRef entities = SU_INVALID;
res = SUModelGetEntities(model, &entities);
CHECK(res);
//unsigned int mesh_index;
aiMesh *mesh;
unsigned int face_count = 0;
aiVector3D vertex;
// Iterate each scene mesh
//for (unsigned int i = 0; i < root_node->mNumMeshes; i++) {
for (unsigned int i = 0; i < scene->mNumMeshes; i++) {
mesh = scene->mMeshes[i];
face_count = mesh->mNumFaces;
// Create a new Group for each Mesh
SUGroupRef grp = SU_INVALID;
res = SUGroupCreate(&grp);
CHECK(res);
res = SUEntitiesAddGroup(entities, grp);
CHECK(res);
SUEntitiesRef gents = SU_INVALID;
res = SUGroupGetEntities(grp, &gents);
CHECK(res);
SUGeometryInputRef geom_input = SU_INVALID;
res = SUGeometryInputCreate(&geom_input);
CHECK(res);
SULoopInputRef outer_loop = SU_INVALID;
aiFace *faces = mesh->mFaces;
unsigned int v_i;
int c = 0;
for (size_t i = 0; i < face_count; i++)
{
// std::cout << "Face " << i << " has " << faces[i].mNumIndices << " vertices.\n";
// Create a Loop for each face
res = SULoopInputCreate(&outer_loop);
for (size_t j = 0; j < faces[i].mNumIndices; j++)
{
v_i = faces[i].mIndices[j];
// std::cout << v_i << " ";
vertex = mesh->mVertices[v_i];
SUPoint3D pt;
pt.x = vertex.x * Scale;
pt.y = vertex.y * Scale;
pt.z = vertex.z * Scale;
res = SUGeometryInputAddVertex(geom_input, &pt);
CHECK(res);
res = SULoopInputAddVertexIndex(outer_loop, c);
CHECK(res);
c++;
}
res = SUGeometryInputAddFace(geom_input, &outer_loop, NULL);
CHECK(res);
SULoopInputRelease(&outer_loop);
}
res = SUEntitiesFill(entities, geom_input, true);
CHECK(res);
SUGeometryInputRelease(&geom_input);
}
std::string outname = (std::string)filename + ".skp";
std::cout << "Writing model...\n";
res = SUModelSaveToFileWithVersion(model, outname.c_str(), SUModelVersion::SUModelVersion_SU2014);
CHECK(res);
if (res == SU_ERROR_NONE)
{
std::cout << "Success." << "\n";
}
res = SUModelRelease(&model);
CHECK(res);
SUTerminate();
// ShellExecute(GetDesktopWindow(), "open", outname.c_str(), NULL, NULL, SW_SHOW);
// system("pause");
return 0;
}
#ifndef A2S_SHOW_SKETCHUP_ERROR_H
#define A2S_SHOW_SKETCHUP_ERROR_H
void output_sketchup_error(SUResult err) {
switch (err) {
case SU_ERROR_NONE:
std::cout << "SU_ERROR_NONE\n";
std::cout << "Indicates Success";
break;
case SU_ERROR_NULL_POINTER_INPUT:
std::cout << "SU_ERROR_NULL_POINTER_INPUT\n";
std::cout << "A pointer for a required input was NULL.";
break;
case SU_ERROR_INVALID_INPUT:
std::cout << "SU_ERROR_INVALID_INPUT\n";
std::cout << "An API object input to the function was not created properly.";
break;
case SU_ERROR_NULL_POINTER_OUTPUT:
std::cout << "SU_ERROR_NULL_POINTER_OUTPUT\n";
std::cout << "A pointer for a required output was NULL. ";
break;
case SU_ERROR_INVALID_OUTPUT:
std::cout << "SU_ERROR_INVALID_OUTPUT\n";
std::cout << "An API object to be written with output from the function was not created properly.";
break;
case SU_ERROR_OVERWRITE_VALID:
std::cout << "SU_ERROR_OVERWRITE_VALID\n";
std::cout << "Indicates that an input object reference already references an object where it was expected to be SU_INVALID.";
break;
case SU_ERROR_GENERIC:
std::cout << "SU_ERROR_GENERIC\n";
std::cout << "Indicates an unspecified error.";
break;
case SU_ERROR_SERIALIZATION:
std::cout << "SU_ERROR_SERIALIZATION\n";
std::cout << "Indicates an error occurred during loading or saving of a file.";
break;
case SU_ERROR_OUT_OF_RANGE:
std::cout << "SU_ERROR_OUT_OF_RANGE\n";
std::cout << "An input contained a value that was outside the range of allowed values.";
break;
case SU_ERROR_NO_DATA:
std::cout << "SU_ERROR_NO_DATA\n";
std::cout << "The requested operation has no data to return to the user. This usually occurs when a request is made for data that is only available conditionally.";
break;
case SU_ERROR_INSUFFICIENT_SIZE:
std::cout << "SU_ERROR_INSUFFICIENT_SIZE\n";
std::cout << "Indicates that the size of an output parameter is insufficient.";
break;
case SU_ERROR_UNKNOWN_EXCEPTION:
std::cout << "SU_ERROR_UNKNOWN_EXCEPTION\n";
std::cout << "An unknown exception occurred.";
break;
case SU_ERROR_MODEL_INVALID:
std::cout << "SU_ERROR_MODEL_INVALID\n";
std::cout << "The model requested is invalid and cannot be loaded.";
break;
case SU_ERROR_MODEL_VERSION:
std::cout << "SU_ERROR_MODEL_VERSION\n";
std::cout << "The model cannot be loaded or saved due to an invalid version.";
break;
default:
std::cout << "Unknown Error #" << err;
}
std::cout << std::endl;
}
#endif
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment