Last active
July 4, 2022 07:51
-
-
Save jimfoltz/0644d189146b4db373903ff59bbef7a9 to your computer and use it in GitHub Desktop.
convert mesh files to .skp using assimp library
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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