Browse Source

Openscad export

Johannes Kreutz 3 years ago
parent
commit
8c1d27d33c
2 changed files with 77 additions and 3 deletions
  1. BIN
      testdata/testbutton.stl
  2. 77 3
      trackpoint-app/transforms.cpp

BIN
testdata/testbutton.stl


+ 77 - 3
trackpoint-app/transforms.cpp

@@ -10,19 +10,31 @@
 #include <osgUtil/IntersectionVisitor>
 #include <osg/PolygonMode>
 #include <vector>
+#include <iostream>
+#include <fstream>
+#include <string>
+#include <math.h>
+
+const char* openScadBase =
+  "$fn = 100;\n"
+  "module optiTrackPointBase(translation, rotation) {\n"
+  "translate(translation) rotate(rotation) cylinder(10, 1, 1, false);\n"
+  "}\n";
 
 class TrackPoint {
 public:
   TrackPoint(osg::Vec3 point, osg::Vec3 normal);
   osg::ref_ptr<osg::MatrixTransform> getUppermostRoot();
+  osg::Vec3 getTranslation();
+  osg::Vec3 getRotation();
 
 protected:
   osg::ref_ptr<osg::MatrixTransform> _translationGroup;
   osg::ref_ptr<osg::MatrixTransform> _rotationGroup;
 
 private:
-  osg::Vec3 point;
-  osg::Vec3 normal;
+  osg::Vec3 _point;
+  osg::Vec3 _normal;
 };
 
 TrackPoint::TrackPoint(osg::Vec3 point, osg::Vec3 normal) {
@@ -39,16 +51,71 @@ TrackPoint::TrackPoint(osg::Vec3 point, osg::Vec3 normal) {
   _translationGroup = new osg::MatrixTransform;
   _translationGroup->addChild(_rotationGroup.get());
   _translationGroup->setMatrix(osg::Matrix::translate(point));
+
+  _point = point;
+  _normal = normal;
 }
 
 osg::ref_ptr<osg::MatrixTransform> TrackPoint::getUppermostRoot() {
   return _translationGroup.get();
 }
 
+osg::Vec3 TrackPoint::getTranslation() {
+  return _point;
+}
+
+osg::Vec3 TrackPoint::getRotation() {
+  printf("YNorm: %lf %lf %lf\n", _normal.x(), _normal.y(), _normal.z());
+
+  osg::Vec3 start = osg::Vec3(0.0f, 0.0f, 1.0f);
+
+  // From https://en.wikipedia.org/wiki/Conversion_between_quaternions_and_Euler_angles
+  osg::Quat quat = osg::Quat(0.0f, 0.0f, 0.0f, 0.0f);
+  quat.makeRotate(start, _normal);
+
+  float sinr_cosp = 2 * (quat.w() * quat.x() + quat.y() * quat.z());
+  float cosr_cosp = 1 - 2 * (quat.x() * quat.x() + quat.y() * quat.y());
+  float xRotation = std::atan2(sinr_cosp, cosr_cosp) * 180.0 / M_PI;
+
+  float sinp = 2 * (quat.w() * quat.y() - quat.z() * quat.x());
+  float yRotation;
+  if (std::abs(sinp) >= 1) {
+    yRotation = std::copysign(M_PI / 2, sinp) * 180.0 / M_PI;
+  } else {
+    yRotation = std::asin(sinp) * 180.0 / M_PI;
+  }
+
+  float siny_cosp = 2 * (quat.w() * quat.z() + quat.x() * quat.y());
+  float cosy_cosp = 1 - 2 * (quat.y() * quat.y() + quat.z() * quat.z());
+  float zRotation = std::atan2(siny_cosp, cosy_cosp) * 180.0 / M_PI;
+
+  return osg::Vec3(xRotation, yRotation, zRotation);
+}
+
+class OpenScadRenderer {
+public:
+  void render(std::vector<TrackPoint*> points);
+};
+
+void OpenScadRenderer::render(std::vector<TrackPoint*> points) {
+  std::ofstream scadFile;
+  scadFile.open("/tmp/output.scad");
+  scadFile << openScadBase;
+  scadFile << "import(\"testbutton.stl\");\n";
+  for (TrackPoint* point: points) {
+    osg::Vec3 translation = point->getTranslation();
+    osg::Vec3 rotation = point->getRotation();
+    scadFile << "optiTrackPointBase([" << translation.x() << "," << translation.y() << "," << translation.z() << "], [" << rotation.x() << "," << rotation.y() << "," << rotation.z() << "]);\n";
+  }
+  scadFile.close();
+  system("openscad -o /tmp/output.stl /tmp/output.scad");
+}
+
 class StoreHandler {
 public:
   void addTrackingPoint(osg::Vec3 point, osg::Vec3 normal);
   StoreHandler(osg::ref_ptr<osg::Group> root);
+  std::vector<TrackPoint*> getPoints();
 
 protected:
   std::vector<TrackPoint*> points;
@@ -67,7 +134,12 @@ StoreHandler::StoreHandler(osg::ref_ptr<osg::Group> root) {
   _root = root;
 }
 
+std::vector<TrackPoint*> StoreHandler::getPoints() {
+  return points;
+}
+
 StoreHandler* storeHandler;
+OpenScadRenderer* openScadRenderer;
 
 class PickHandler: public osgGA::GUIEventHandler {
 public:
@@ -113,6 +185,7 @@ bool PickHandler::handle(const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapt
       moveTo(result.localIntersectionPoint);
       rotateToNormalVector(result.localIntersectionNormal);
       storeHandler->addTrackingPoint(result.localIntersectionPoint, result.localIntersectionNormal);
+      openScadRenderer->render(storeHandler->getPoints());
     }
   }
   return false;
@@ -136,7 +209,7 @@ int main(int argc, char** argv) {
     viewer.realize();
 
     // Add axesNode under root
-    osg::ref_ptr<osg::Node> axesNode = osgDB::readNodeFile("../../testdata/zPlate_0.stl");
+    osg::ref_ptr<osg::Node> axesNode = osgDB::readNodeFile("../../testdata/testbutton.stl");
     if (!axesNode) {
         printf("Origin node not loaded, model not found\n");
         return 1;
@@ -148,6 +221,7 @@ int main(int argc, char** argv) {
     viewer.setCameraManipulator(tm);
 
     storeHandler = new StoreHandler(root);
+    openScadRenderer = new OpenScadRenderer();
 
     osg::ref_ptr<PickHandler> picker = new PickHandler();
     root->addChild(picker->getOrCreateSelectionCylinder());