ProjectStore.cpp 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212
  1. // Include own headers
  2. #include "ProjectStore.hpp"
  3. // Include modules
  4. #include "MainWindow.hpp"
  5. #include "StringBasics.hpp"
  6. #include "TrackPointRenderer.hpp"
  7. // Include dependencies
  8. #include <typeinfo>
  9. #include <iostream>
  10. #define META_NAMESPACE "tk-ar-tracking"
  11. ProjectStore::ProjectStore() {
  12. _projectLoaded = false;
  13. _projectModified = false;
  14. load3mfLib();
  15. }
  16. ProjectStore::~ProjectStore() {
  17. }
  18. void ProjectStore::loadMesh(std::string meshFile) {
  19. if (StringBasics::endsWithCaseInsensitive(meshFile, ".STL")) {
  20. printf("Currently unsupported.\n");
  21. } else if (StringBasics::endsWithCaseInsensitive(meshFile, ".3MF")) {
  22. _projectLoaded = true;
  23. // Read 3MF file
  24. Lib3MF::PReader reader = _project->QueryReader("3mf");
  25. reader->ReadFromFile(meshFile);
  26. render3MFMesh();
  27. MainWindow::getInstance()->renderView(Edit);
  28. } else {
  29. // TODO: Show error popup
  30. printf("Unsupported file type.\n");
  31. }
  32. }
  33. bool ProjectStore::loadProject(std::string projectFile) {
  34. if (!_projectLoaded) {
  35. Lib3MF::PReader reader = _project->QueryReader("3mf");
  36. reader->ReadFromFile(projectFile);
  37. _projectLoaded = true;
  38. _projectModified = false;
  39. loadMetaData();
  40. return true;
  41. }
  42. return false;
  43. }
  44. bool ProjectStore::saveProject() {
  45. if (_projectFile != "") {
  46. return saveProject(_projectFile);
  47. }
  48. return false;
  49. }
  50. bool ProjectStore::saveProject(std::string path) {
  51. updateMetaData();
  52. Lib3MF::PWriter writer = _project->QueryWriter("3mf");
  53. writer->WriteToFile(path);
  54. _projectFile = path;
  55. return true;
  56. }
  57. bool ProjectStore::exportProject(std::string path, ExportSettings settings) {
  58. return false; // TODO
  59. }
  60. void ProjectStore::updateNormalModifier(osg::Vec3 modifier) {
  61. _normalModifier = modifier;
  62. }
  63. osg::Vec3 ProjectStore::getNormalModifier() {
  64. return _normalModifier;
  65. }
  66. std::vector<OptiTrackPoint*> ProjectStore::getOptiTrackPoints() {
  67. return _optiTrackPoints;
  68. }
  69. void ProjectStore::addOptiTrackPoint(osg::Vec3 point, osg::Vec3 normal) {
  70. OptiTrackPoint* optiTrackPoint = new OptiTrackPoint(point, normal, _normalModifier, _optiTrackSettings.length, _optiTrackSettings.radius);
  71. _optiTrackPoints.push_back(optiTrackPoint);
  72. }
  73. void ProjectStore::removeOptiTrackPoint() {
  74. // TODO
  75. }
  76. void ProjectStore::updateOptiTrackSettings(OptiTrackSettings optiTrackSettings) {
  77. _optiTrackSettings = optiTrackSettings;
  78. }
  79. OptiTrackSettings ProjectStore::getOptiTrackSettings() {
  80. return _optiTrackSettings;
  81. }
  82. void ProjectStore::load3mfLib() {
  83. _wrapper = Lib3MF::CWrapper::loadLibrary();
  84. _project = _wrapper->CreateModel();
  85. }
  86. void ProjectStore::render3MFMesh() {
  87. // Get meshes
  88. Lib3MF::PMeshObjectIterator meshIterator = _project->GetMeshObjects();
  89. // Our use case supports just a single mesh per project
  90. if (meshIterator->Count() != 1) {
  91. // TODO: Show error popup
  92. printf("Not 1 mesh: %llu\n", meshIterator->Count());
  93. return;
  94. }
  95. meshIterator->MoveNext();
  96. Lib3MF::PMeshObject mesh = meshIterator->GetCurrentMeshObject();
  97. // Load vertices and triangles and render them
  98. std::vector<Lib3MF::sPosition> verticesBuffer;
  99. mesh->GetVertices(verticesBuffer);
  100. std::vector<Lib3MF::sTriangle> triangleBuffer;
  101. mesh->GetTriangleIndices(triangleBuffer);
  102. // Create osg style arrays
  103. osg::ref_ptr<osg::Vec3Array> vertices = new osg::Vec3Array;
  104. osg::ref_ptr<osg::Vec3Array> normals = new osg::Vec3Array;
  105. // Convert data to osg format and calculate vertex normals
  106. for (const Lib3MF::sTriangle triangle: triangleBuffer) {
  107. // Create osg vectors
  108. osg::Vec3 vertex[3] = {};
  109. for (char i = 0; i < 3; i++) {
  110. vertex[i] = osg::Vec3(verticesBuffer[triangle.m_Indices[i]].m_Coordinates[0], verticesBuffer[triangle.m_Indices[i]].m_Coordinates[1], verticesBuffer[triangle.m_Indices[i]].m_Coordinates[2]);
  111. }
  112. // Calculate normal
  113. osg::Vec3 edgeOne = vertex[1].operator-(vertex[0]);
  114. osg::Vec3 edgeTwo = vertex[2].operator-(vertex[0]);
  115. osg::Vec3 normal = edgeOne.operator^(edgeTwo);
  116. normal.normalize();
  117. // Store them
  118. for (int i = 0; i < 3; i++) {
  119. vertices->push_back(vertex[i]);
  120. normals->push_back(normal);
  121. }
  122. }
  123. // Call renderer
  124. MainWindow* mainWindow = MainWindow::getInstance();
  125. mainWindow->getOsgWidget()->renderBaseMesh(vertices, normals);
  126. }
  127. void ProjectStore::updateMetaData() {
  128. Lib3MF::PMetaDataGroup metaData = _project->GetMetaDataGroup();
  129. try {
  130. Lib3MF::PMetaData versionInformation = metaData->GetMetaDataByKey(META_NAMESPACE, "format");
  131. } catch (Lib3MF::ELib3MFException &e) {
  132. metaData->AddMetaData(META_NAMESPACE, "format", "1.0.0", "string", true);
  133. }
  134. json optiTrackData = json::array();
  135. for (OptiTrackPoint* optiTrackPoint: _optiTrackPoints) {
  136. optiTrackData.push_back({
  137. {"point", osgVecToStdVec(optiTrackPoint->getTranslation())},
  138. {"normal", osgVecToStdVec(optiTrackPoint->getNormal())},
  139. {"normalModifier", osgVecToStdVec(optiTrackPoint->getNormalModifier())},
  140. {"length", optiTrackPoint->getLength()},
  141. {"radius", optiTrackPoint->getRadius()}
  142. });
  143. }
  144. try {
  145. Lib3MF::PMetaData optiTrackPoints = metaData->GetMetaDataByKey(META_NAMESPACE, "optitrack");
  146. optiTrackPoints->SetValue(optiTrackData.dump());
  147. } catch (Lib3MF::ELib3MFException &e) {
  148. metaData->AddMetaData(META_NAMESPACE, "optitrack", optiTrackData.dump(), "string", true);
  149. }
  150. }
  151. void ProjectStore::loadMetaData() {
  152. Lib3MF::PMetaDataGroup metaData = _project->GetMetaDataGroup();
  153. try {
  154. Lib3MF::PMetaData versionInformation = metaData->GetMetaDataByKey(META_NAMESPACE, "format");
  155. } catch (Lib3MF::ELib3MFException &e) {
  156. // TODO: Alert not a TrackpointApp poject
  157. }
  158. Lib3MF::PMetaData optiTrackString;
  159. try {
  160. optiTrackString = metaData->GetMetaDataByKey(META_NAMESPACE, "optitrack");
  161. } catch (Lib3MF::ELib3MFException &e) {
  162. // TODO: Something is wrong with the file
  163. }
  164. auto optiTrackData = json::parse(optiTrackString->GetValue());
  165. _optiTrackPoints.clear();
  166. for (const auto pointData: optiTrackData) {
  167. osg::Vec3f point = osg::Vec3f(pointData["point"][0], pointData["point"][1], pointData["point"][2]);
  168. osg::Vec3f normal = osg::Vec3f(pointData["normal"][0], pointData["normal"][1], pointData["normal"][2]);
  169. osg::Vec3f normalModifier = osg::Vec3f(pointData["normalModifier"][0], pointData["normalModifier"][1], pointData["normalModifier"][2]);
  170. OptiTrackPoint* optiTrackPoint = new OptiTrackPoint(point, normal, normalModifier, static_cast<double>(pointData["length"]), static_cast<double>(pointData["radius"]));
  171. _optiTrackPoints.push_back(optiTrackPoint);
  172. }
  173. render3MFMesh();
  174. MainWindow::getInstance()->renderView(Edit);
  175. MainWindow::getInstance()->getOsgWidget()->getPointRenderer()->render(MainWindow::getInstance()->getEditWiget()->getSelectedTrackingSystem());
  176. }
  177. std::vector<float> ProjectStore::osgVecToStdVec(osg::Vec3f input) {
  178. std::vector<float> vector;
  179. vector.push_back(input.x());
  180. vector.push_back(input.y());
  181. vector.push_back(input.z());
  182. return vector;
  183. }
  184. osg::Vec3f ProjectStore::stdVecToOsgVec(std::vector<float> input) {
  185. return osg::Vec3f(input[0], input[1], input[2]);
  186. }