Last active
May 10, 2023 17:58
-
-
Save oteguro/9505967daf942c939a5bf4183412bafe to your computer and use it in GitHub Desktop.
This file contains hidden or 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
// simplygon_minimal_example.cpp | |
#define WIN32_LEAN_AND_MEAN | |
#include <fstream> | |
#include <cassert> | |
#include <cstdio> | |
#include <cstdint> | |
#include <vector> | |
#include <string> | |
#include <windows.h> | |
#include <tchar.h> | |
#include <SimplygonSDK.h> | |
namespace | |
{ | |
typedef int (CALLBACK* PROC_INITIALIZE_SIMPLYGON)(const char* license_data, SimplygonSDK::ISimplygonSDK **pInterfacePtr); | |
typedef void (CALLBACK* PROC_DEINITIALIZE_SIMPLYGON)(); | |
void LoadLicenseTextFromFile(std::string& text, LPCTSTR licencePath) | |
{ | |
text.clear(); | |
std::ifstream t; | |
t.open(licencePath); | |
std::string line; | |
while (t) | |
{ | |
std::getline(t, line); | |
text += line; | |
} | |
t.close(); | |
} | |
// Simplygon error callback. | |
class SimplygonErrorHandler : public SimplygonSDK::rerrorhandler | |
{ // Error handler. | |
virtual void HandleError( | |
SimplygonSDK::IObject *object, | |
const char *interfacename, | |
const char *methodname, | |
SimplygonSDK::rid errortype, | |
const char *errortext | |
) | |
{ | |
std::fprintf(stderr, "A SimplygonSDK error occured!\n"); | |
std::fprintf(stderr, "\tInterface: %s (%p)\n", interfacename, object); | |
std::fprintf(stderr, "\tMethod: %s\n", methodname); | |
std::fprintf(stderr, "\tError Type: %d\n", errortype); | |
std::fprintf(stderr, "\tError Description: %s\n", errortext); | |
#if _DEBUG | |
__debugbreak(); | |
#endif | |
exit(1); | |
} | |
}; // class SimplygonErrorHandler | |
static SimplygonErrorHandler s_errorHandler; | |
class SimpleSimplygonInterface | |
{ | |
SimplygonSDK::ISimplygonSDK* sdkInterface; | |
HINSTANCE dllHandle; | |
PROC_INITIALIZE_SIMPLYGON InitializeSimplygonSDKPtr; | |
PROC_DEINITIALIZE_SIMPLYGON DeinitializeSimplygonSDKPtr; | |
public: | |
SimpleSimplygonInterface() | |
: sdkInterface(nullptr) | |
, dllHandle (nullptr) | |
, InitializeSimplygonSDKPtr (nullptr) | |
, DeinitializeSimplygonSDKPtr(nullptr) | |
{ | |
} | |
bool Initialize(LPCTSTR dllPath, LPCTSTR licencePath) | |
{ | |
// Load library DLL. | |
dllHandle = LoadLibrary (dllPath); | |
assert(dllHandle != nullptr); // Please check your DLL path. | |
if (dllHandle == nullptr) | |
{ | |
return false; | |
} | |
// Retrieve Simplygon SDK API. | |
InitializeSimplygonSDKPtr = (PROC_INITIALIZE_SIMPLYGON) GetProcAddress(dllHandle, "InitializeSimplygonSDK"); | |
DeinitializeSimplygonSDKPtr = (PROC_DEINITIALIZE_SIMPLYGON)GetProcAddress(dllHandle, "DeinitializeSimplygonSDK"); | |
assert(InitializeSimplygonSDKPtr != nullptr); | |
assert(DeinitializeSimplygonSDKPtr != nullptr); | |
// Load license. | |
std::string licenseText; | |
LoadLicenseTextFromFile(licenseText, licencePath); | |
assert(!licenseText.empty()); // Please check your license path. | |
// Initialize Simplygon. | |
int retval = InitializeSimplygonSDKPtr(licenseText.c_str(), &sdkInterface); | |
if (retval != SimplygonSDK::SG_ERROR_NOERROR) | |
{ | |
return false; | |
} | |
sdk().SetErrorHandler(&s_errorHandler); | |
fprintf(stderr, "Initialize Simplygon SDK[%s]\n", sdkInterface->GetVersion()); | |
return true; | |
} | |
void Deinitialize() | |
{ | |
if (dllHandle == nullptr) | |
{ | |
return; | |
} | |
DeinitializeSimplygonSDKPtr(); | |
FreeLibrary(dllHandle); | |
dllHandle = nullptr; | |
InitializeSimplygonSDKPtr = nullptr; | |
DeinitializeSimplygonSDKPtr = nullptr; | |
sdkInterface = nullptr; | |
} | |
SimplygonSDK::ISimplygonSDK& sdk() | |
{ | |
assert( sdkInterface != nullptr); // Not initialized yet. | |
return *sdkInterface; | |
} | |
}; // class SimpleSimplygonInterface | |
} // unnamed namespace | |
namespace sample | |
{ | |
struct Vertex { float x, y, z; Vertex() :x(0), y(0), z(0) {} }; // struct Vertex | |
void GenerateTrianglePolygonMesh(std::vector<Vertex>& vtx, std::vector<int32_t>& idx) | |
{ | |
const int gridX = 4; | |
const int gridY = 4; | |
for (int y = 0; y < gridY; ++y) | |
{ | |
for (int x = 0; x < gridX; ++x) | |
{ | |
Vertex v; | |
v.x = static_cast<float>(x); | |
v.y = static_cast<float>(y); | |
v.z = 0; | |
vtx.push_back(v); | |
} | |
} | |
int triangleCount = (gridX - 1) * (gridY - 1) * 2; | |
for (int t = 0; t < triangleCount; ++t) | |
{ | |
int quadIndex = (t / 2); | |
int quadX = (quadIndex) % (gridX - 1); | |
int quadY = (quadIndex) / (gridX - 1); | |
if((t%2) == 0) | |
{ | |
int i0 = ((quadY ) * gridX) + quadX; | |
int i1 = i0 + 1; | |
int i2 = ((quadY + 1) * gridX) + quadX; | |
idx.push_back(i0); | |
idx.push_back(i1); | |
idx.push_back(i2); | |
} | |
else | |
{ | |
int i0 = ((quadY ) * gridX) + quadX + 1; | |
int i1 = ((quadY + 1) * gridX) + quadX + 1; | |
int i2 = i1 - 1; | |
idx.push_back(i0); | |
idx.push_back(i1); | |
idx.push_back(i2); | |
} | |
} | |
} | |
void DumpTrianglePolygonMesh(std::vector<Vertex>& vtx, std::vector<int32_t>& idx, const char* annotation) | |
{ | |
fprintf(stderr, "----------------\n[%s]\n", annotation); | |
fprintf(stderr, "vtx count = %d / idx count = %d\n", static_cast<int>(vtx.size()), static_cast<int>(idx.size())); | |
for (auto& v : vtx) | |
{ | |
fprintf(stderr, "vtx [%1.1f, %1.1f, %1.1f]\n", v.x, v.y, v.z); | |
} | |
fprintf(stderr, "\n"); | |
int triangleCount = static_cast<int>(idx.size()) / 3; | |
for (int i = 0; i < triangleCount; ++i) | |
{ | |
int ix = i * 3; | |
fprintf(stderr, "tri [%2d]-[%2d]-[%2d]\n", idx[ix], idx[ix + 1], idx[ix + 2]); | |
} | |
fprintf(stderr, "\n"); | |
} | |
void SetReductionSettings(SimplygonSDK::spReductionProcessor rp, unsigned int screenSize) | |
{ | |
SimplygonSDK::spReductionSettings reductionSettings = rp->GetReductionSettings(); | |
reductionSettings->SetReductionTargets(SimplygonSDK::SG_REDUCTIONTARGET_ONSCREENSIZE); | |
reductionSettings->SetUseAutomaticSymmetryDetection(true); | |
reductionSettings->SetSymmetryDetectionTolerance(0.01f); | |
reductionSettings->SetDataCreationPreferences(SimplygonSDK::SG_DATACREATIONPREFERENCES_PREFER_ORIGINAL_DATA); // SG_DATACREATIONPREFERENCES_ONLY_USE_ORIGINAL_DATA かな. | |
reductionSettings->SetOnScreenSize(screenSize); | |
reductionSettings->SetStopCondition(SimplygonSDK::SG_STOPCONDITION_ANY); | |
reductionSettings->SetMaxDeviation(0.01f); | |
reductionSettings->SetInwardMoveMultiplier(0.01f); | |
reductionSettings->SetOutwardMoveMultiplier(0.0f); | |
} | |
#define SDK() simplygon.sdk() | |
void DoSimplePolygonReduction(SimpleSimplygonInterface& simplygon, std::vector<Vertex>& vtx, std::vector<int32_t>& idx) | |
{ | |
int32_t vertexCount = static_cast<int32_t>(vtx.size()); | |
int32_t indexCount = static_cast<int32_t>(idx.size()); | |
int32_t triangleCount = indexCount / 3; | |
//---------------- | |
// Import geometry data. | |
SimplygonSDK::spScene scene = SDK().CreateScene(); | |
SimplygonSDK::spGeometryData geometry = SDK().CreateGeometryData(); | |
SimplygonSDK::spRealArray position = geometry->GetCoords(); | |
geometry->SetVertexCount(vertexCount); | |
geometry->SetTriangleCount(triangleCount); | |
SimplygonSDK::spRealArray vertexPositionArray = geometry->GetCoords(); | |
SimplygonSDK::spRidArray indexArray = geometry->GetVertexIds(); | |
for (int i = 0; i < vertexCount; ++i) | |
{ | |
vertexPositionArray->SetTuple(i, &(vtx[i].x)); | |
} | |
for (int i = 0; i < indexCount; ++i) | |
{ | |
indexArray->SetItem(i, idx[i]); | |
} | |
SimplygonSDK::spSceneMesh sceneMesh = SDK().CreateSceneMesh(); | |
sceneMesh->SetGeometry(geometry); | |
scene->GetRootNode()->AddChild(sceneMesh); | |
//---------------- | |
// Execute polygon reduction. | |
const unsigned int screenSize = 1000; | |
SimplygonSDK::spReductionProcessor rp = SDK().CreateReductionProcessor(); | |
SetReductionSettings(rp, screenSize); // You can choose various settings in simplygon... | |
rp->SetScene(scene); | |
rp->RunProcessing(); | |
//---------------- | |
// Retrieve geometry data. | |
SimplygonSDK::spGeometryData simplifiedGeometry = sceneMesh->GetGeometry(); | |
SimplygonSDK::spRealArray simplifiedVertexArray = simplifiedGeometry->GetCoords(); | |
SimplygonSDK::spRidArray simplifiedIndexArray = simplifiedGeometry->GetVertexIds(); | |
unsigned int newVertexCount = simplifiedGeometry->GetVertexCount (); | |
unsigned int newIndexCount = simplifiedGeometry->GetTriangleCount() * 3; | |
assert(newVertexCount > 0); | |
assert(newIndexCount > 0); | |
std::vector<Vertex> ov(newVertexCount, Vertex()); | |
std::vector<int32_t> oi(newIndexCount, 0); | |
for (unsigned int i = 0; i < newVertexCount; ++i) | |
{ | |
SimplygonSDK::spRealData vertexTuple = SDK().CreateRealData(); | |
simplifiedVertexArray->GetTuple(i, vertexTuple); | |
ov[i].x = vertexTuple[0]; | |
ov[i].y = vertexTuple[1]; | |
ov[i].z = vertexTuple[2]; | |
} | |
for (unsigned int i = 0; i < newIndexCount; ++i) | |
{ | |
uint32_t newIndex = simplifiedIndexArray->GetItem(i); | |
oi[i] = newIndex; | |
} | |
std::swap(ov, vtx); | |
std::swap(oi, idx); | |
} | |
#ifdef SDK | |
#undef SDK | |
#endif | |
} // namespace sample | |
using namespace sample; | |
int main(int argc, char* argv[]) | |
{ | |
// DLL / license path. | |
// Note : If you would like to use multibyte code set, use LPCSTR instead. | |
LPCTSTR dllPath = L"C:\\Program Files\\Simplygon\\8\\Tools\\SimplygonRedistUE4\\Dependencies\\Common\\Engine\\Binaries\\ThirdParty\\NotForLicensees\\Simplygon\\SimplygonSDKRuntimeReleasex64.dll"; | |
LPCTSTR licPath = L"C:\\Users\\[Your user name]\\AppData\\Local\\DonyaLabs\\SimplygonSDK\\Simplygon_8_license.dat"; | |
SimpleSimplygonInterface simplygon; | |
simplygon.Initialize(dllPath, licPath); | |
{ | |
std::vector<Vertex> vtx; | |
std::vector<int32_t> idx; | |
GenerateTrianglePolygonMesh(vtx, idx); | |
DumpTrianglePolygonMesh(vtx, idx, "before reduction."); | |
DoSimplePolygonReduction(simplygon, vtx, idx); | |
DumpTrianglePolygonMesh(vtx, idx, "after reduction."); | |
} | |
simplygon.Deinitialize(); | |
return 0; | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment