Commits

Anonymous committed 054aca6

Implement a thrift service

Comments (0)

Files changed (99)

 \.pyc$
 \.pyo$
 \.swp$
+\.swo$
+\.swn$
 \.tmp$
 ^_generated_
 ^\.cache_
     -mfpmath=sse -msse -msse2 -mssse3 -msse4.1
     -fno-math-errno -ffinite-math-only -fno-signed-zeros
     -fno-trapping-math -fno-signaling-nans
-    -fomit-frame-pointer -falign-labels=1 -falign-jumps=1
+    -fno-omit-frame-pointer -falign-labels=1 -falign-jumps=1
     -funroll-loops  -finline-functions -Wall -Wextra
     -Wconversion -Wpointer-arith -Wcast-qual
     -g)#0 -s)
 include(include/CMakeLists.txt)
 add_subdirectory(./src lib)
 if (HAVE_GSOAP)
-    add_subdirectory(./service/)
     add_subdirectory(./service/soap)
-    add_subdirectory(./service/soap2)
+    add_subdirectory(./service/soap_outdated)
 endif ()
 if (HAVE_THRIFT)
     add_subdirectory(./service/thrift)

clients/matlab-axis/Makefile

-####### Compiler, tools and options
-
-JAR			  = /usr/bin/jar -cvf
-JAVAC 		  = /usr/bin/javac
-JAVA		  = /usr/bin/java
-WSDL2J		  = org.apache.axis.wsdl.WSDL2Java
-CLASSPATH	  = "/usr/share/java/axis.jar:\
-				/usr/share/java/commons-discovery.jar:\
-				/usr/share/java/commons-logging.jar:\
-				/usr/share/java/jaxrpc.jar:\
-				/usr/share/java/saaj.jar:\
-				/usr/share/java/xercesImpl.jar:\
-				/usr/share/java/xml-apis.jar:\
-				/usr/share/java/log4j-1.2.jar:\
-				/usr/share/java/wsdl4j.jar:\
-				/usr/share/java/axis/axis.jar:\
-				/usr/share/java/axis/jaxrpc.jar:\
-				/usr/share/java/axis/saaj.jar:\
-				./"
-PATH 		  = $(subst : ,:,$(CLASSPATH))
-WSDL		  = "http://lxpowerboz:88/services/cpp/RayCross?wsdl"
-DEL			  = /bin/rm -rvf
-
-####### Files
-
-PREFIX		  = de/mpg/ipp/hgw/boz/gsoap/raycross/
-SOURCES       = $(PREFIX)RayCrossServiceStub.java \
-				$(PREFIX)RayCrossServicePortType.java \
-				$(PREFIX)RayCrossService.java \
-				$(PREFIX)RayCrossServiceLocator.java \
-				$(PREFIX)CartesianGrid.java \
-				$(PREFIX)Distance.java \
-				$(PREFIX)ElementLoad.java \
-				$(PREFIX)Loads.java \
-				$(PREFIX)Machine.java \
-				$(PREFIX)MeshedModel.java \
-				$(PREFIX)Points3D.java \
-				$(PREFIX)PolygonList.java \
-				$(PREFIX)PolygonPlaneIntersection.java \
-				$(PREFIX)ResultGetAreas.java \
-				$(PREFIX)ResultGetRandomFixN.java \
-				$(PREFIX)ResultIntersection.java
-CLASSES       =  $(subst .java,.class,$(SOURCES))
-DIR			  = de
-JARFILE		  = raycross.jar
-
-####### Implicit rules
-
-%.class: %.java
-	$(JAVAC) -classpath $(PATH) $<
-
-####### Build rules
-
-all: jar
-
-$(CLASSES): $(SOURCES)
-
-$(SOURCES): $(DIR)
-
-$(DIR): Makefile
-	$(JAVA) -cp $(PATH) $(WSDL2J) $(WSDL)
-
-jar: $(CLASSES) Makefile
-	$(JAR) $(JARFILE) ./$(PREFIX)*.class
-
-FORCE:
-
-###### Clean
-clean:
-	$(DEL) $(CLASSFILE) $(TARGET) $(CLASSES) $(SOURCES) $(DIR) $(JARFILE)
-

clients/matlab-axis/README

-Java-Axis client to use with matlab.
-
-To build jar file simply run:
-    make

include/GridCache.h

     template<class ItemType>
     void GridCache<ItemType>::cacheItem(const ItemType *item)
     {
-        Logger &logger = Logger::getLogger();
-        logger.getDebugSink()<<"GridCache cache item "<<std::hex<<item;
+        //Logger &logger = Logger::getLogger();
+        //logger.getDebugSink()<<"GridCache cache item "<<std::hex<<item;
         bool cached = false; //safety check, all items must be cached
 
         //Algorithm:

service/MeshSrvBase.h

-// MeshSrvBase.cpp - base server class, part of MeshLib.
-// Copyright 2013 Sergey Bozhenkov, boz at ipp.mpg.de
-// Licensed under GPLv3 or later, see the COPYING file.
-#ifndef MESHSRVBASE_JP3C62R
-#define MESHSRVBASE_JP3C62R
-
-#include "ContainerOfIdItems.h"
-#include <LinAlg/Vector3D.h>
-#include <Slog/Logger.h>
-#include <vector>
-#include <string>
-
-namespace meshlib
-{ 
-    class SurfaceMesh;
-    class SurfaceMeshSet;
-    class VolumeMesh;
-} //namespace meshlib
-
-namespace meshsrv
-{
-    using slog::Logger;
-    using std::vector;
-    using std::string;
-    using meshlib::ContainerOfIdItems;
-    using meshlib::SurfaceMesh;
-    using meshlib::SurfaceMeshSet;
-    using meshlib::VolumeMesh;
-    using linalg::Vector3D;
-    
-    // =========================================================================
-    /// @brief Base server class, provides all operations but in
-    /// terms of native library types.
-    // =========================================================================
-    class MeshSrvBase
-    {
-        public:
-            MeshSrvBase() : logger(Logger::getLogger()) {};
-            ~MeshSrvBase(){};
-            
-            //void dropDegeneratedPolygons(const SurfaceMesh &inMesh,
-                                         //SurfaceMesh &outMesh);
-            void refineMesh(const SurfaceMesh &inMesh,
-                            double threshold,
-                            SurfaceMesh &outMesh);
-            void triangulateMesh(const SurfaceMesh &inMesh,
-                                 SurfaceMesh &outMesh);
-            void combineMeshes(const SurfaceMeshSet &meshSet,
-                               SurfaceMesh &mesh);
-            void getPolygonNormals(const vector<size_t> &polygonIds,
-                                   const SurfaceMesh &mesh,
-                                   vector<Vector3D> &normals);
-            void getPolygonCenters(const vector<size_t> &polygonIds,
-                                   const SurfaceMesh &mesh,
-                                   double relTol, double absTol,
-                                   vector<Vector3D> &centers);
-            void getPolygonAreas(const vector<size_t> &polygonIds,
-                                 const SurfaceMesh &mesh,
-                                 vector<double> &areas);
-            void getMeshArea(const SurfaceMesh &mesh,
-                             double &area);
-
-            void getPolyhedronCenters(const vector<size_t> &polyhedronIds,
-                                      const VolumeMesh &mesh,
-                                      vector<Vector3D> &centers);
-            void getPolyhedronSurfaceAreas(const vector<size_t> &polyhedronIds,
-                                           const VolumeMesh &mesh,
-                                           vector<double> &areas);
-            void getPolyhedronVolumes(const vector<size_t> &polyhedronIds,
-                                      const VolumeMesh &mesh,
-                                      vector<double> &volumes);
-            void getMeshVolume(const VolumeMesh &mesh,
-                               double &volume);
-
-           //void getUniformRandomPoints(size_t numPoints,
-                                       //const SurfaceMesh &mesh,
-                                       //::geometry::Points3D& _return,
-           //void getRandomPointsForPolygon(std::vector< ::geometry::Points3D> & _return, const int32_t numPoints, const std::vector<int32_t> & polygonIds, const SurfaceMeshWrap& mesh) {
-
-            void getBuildInfo(string& info);
-
-        private:
-            Logger &logger;
-            template <class T>
-            bool checkContainerEmpty(const ContainerOfIdItems<T> &mesh,
-                                     const string &contName) const;
-            template <class T>
-            bool checkVectorEmpty(const vector<T> &vec,
-                                  const string &vecName) const;
-    };
-    //
-    // =========================================================================
-    /// @brief Check if vector is empty, use vector name to log the result.
-    // =========================================================================
-    template <class T>
-    bool MeshSrvBase::checkVectorEmpty(const vector<T> &vec,
-                                       const string &vecName) const
-    {
-        if (vec.empty())
-        {
-            logger.getDebugSink()<<"empty vector "<<vecName;
-            return true;
-        }
-        return false;
-    }
-
-    template <class T>
-    bool MeshSrvBase::checkContainerEmpty(const ContainerOfIdItems<T> &cont,
-                                          const string &contName) const
-    {
-        if (cont.getNumItems() == 0)
-        {
-            logger.getDebugSink()<<"empty "<<contName;
-            return true;
-        }
-        return false;
-    }
-
-
-
-
-    ////  void intersectSegmentMesh(HitPointsAndPolyLoads& _return, const  ::geometry::Points3D& starts, const  ::geometry::Points3D& stops, const MeshSet& meshSet) {
-    ////    // Your implementation goes here
-    ////    printf("intersectSegmentMesh\n");
-    ////  }
-    ////
-    ////  void calculatePolygonLoads(std::vector<PolygonEventCounter> & _return, const std::vector<PolygonId> & polygons) {
-    ////    // Your implementation goes here
-    ////    printf("calculatePolygonLoads\n");
-    ////  }
-    ////
-    ////  void intersectMeshPlane(std::vector<PolygonPlaneIntersection> & _return, const  ::geometry::Plane& plane, const MeshSet& meshSet) {
-    ////    // Your implementation goes here
-    ////    printf("intersectMeshPlane\n");
-    ////  }
-    ////
-    ////  void intersectMeshPhiPlane(std::vector<PolygonPlaneIntersection> & _return, const double phi, const MeshSet& meshSet) {
-    ////    // Your implementation goes here
-    ////    printf("intersectMeshPhiPlane\n");
-    ////  }
-    ////
-    ////
-    ////  void transformPoints( ::geometry::Points3D& _return, const  ::geometry::Points3D& points, const  ::geometry::Transformation& trans) {
-    ////    // Your implementation goes here
-    ////    printf("transformPoints\n");
-    ////  }
-    ////
-    ////  void transformMesh( ::componentsdb2::SurfaceMesh& _return, const SurfaceMeshWrap& mesh, const  ::geometry::Transformation& trans) {
-    ////    // Your implementation goes here
-    ////    printf("transformMesh\n");
-    ////  }
-    ////
-    ////  void rotatePointsToroidally( ::geometry::Points3D& _return, const  ::geometry::Points3D& points, const double angle) {
-    ////    // Your implementation goes here
-    ////    printf("rotatePointsToroidally\n");
-    ////  }
-    ////
-    ////  void rotateMeshToroidally( ::componentsdb2::SurfaceMesh& _return, const SurfaceMeshWrap& mesh, const double angle) {
-    ////    // Your implementation goes here
-    ////    printf("rotateMeshToroidally\n");
-    ////  }
-    ////
-    ////  void getPointPolygonDistance(std::vector<std::vector<double> > & _return, const  ::geometry::Points3D& points, const std::vector<int32_t> & polygonIds, const SurfaceMeshWrap& mesh) {
-    ////    // Your implementation goes here
-    ////    printf("getPointPolygonDistance\n");
-    ////  }
-    ////
-    ////  void getClosestPolygon(std::vector<PolygonId> & _return, const  ::geometry::Points3D& points, const MeshSet& meshSet) {
-    ////    // Your implementation goes here
-    ////    printf("getClosestPolygon\n");
-    ////  }
-    ////
-    ////  void getContainingPolygons(std::vector<std::vector<PolygonId> > & _return, const  ::geometry::Points3D& points, const MeshSet& meshSet, const double tolerance) {
-    ////    // Your implementation goes here
-    ////    printf("getContainingPolygons\n");
-    ////  }
-    ////
-    ////
-    ////
-    ////  int64_t getTimeStamp() {
-    ////    // Your implementation goes here
-    ////    printf("getTimeStamp\n");
-    ////  }
-
-} //namespace meshsrv
-#endif /* end of include guard: MESHSRVBASE_JP3C62R */
+Some service implementations build on top of the library.
+This part is not required for straight library usage,
+you may simply ignore it.
+There are two service variants:
+ * SOAP - with gSOAP
+ * Apache Thrift
+They both relay on the operations in base/MeshSrvBase*,
+and conversion/* classes for type conversions.

service/base/MeshSrvBase.cpp

+// MeshSrvBase.cpp - MeshSrvBase class, part of MeshLib.
+// Copyright 2013 Sergey Bozhenkov, boz at ipp.mpg.de
+// Licensed under GPLv3 or later, see the COPYING file.
+#include "MeshSrvBase.h"
+#include "Segment.h"
+#include "Transformation.h"
+#include "SurfaceMesh.h" 
+#include "SurfaceMeshSet.h"
+#include "VolumeMesh.h"
+#include "srvconfig.h"
+#include "../conversion/Exceptions.h"
+#include <sstream>
+#include <stdexcept>
+using namespace meshsrvbase;
+using namespace meshlib;
+using namespace linalg;
+using namespace std;
+
+void MeshSrvBase::intersectSegmentMesh(const vector<Segment> &segments,
+                                       SurfaceMeshSet &meshSet,
+                                       vector<Point3D> &points,
+                                       vector<size_t> &meshIds,
+                                       vector<size_t> &polyIds,
+                                       vector<size_t> &polyEvents,
+                                       vector<size_t> &meshEvents)
+{
+    logger.getInfoSink()<<"service function "<<__FUNCTION__;
+    points.resize(0);
+    meshIds.resize(0);
+    polyIds.resize(0);
+    polyEvents.resize(0);
+    if (checkContainerEmpty(meshSet, "surface mesh set"))
+    {
+        logger.getInfoSink()<<"empty input, no processing required";
+        return;
+    }
+    logger.getDebugSink()<<"do segment intersection, "
+                         <<segments.size()<<" segments";
+    vector<const AbstractPolygon*> polys;
+    vector<Point3D> points_raw; // will contain invalid points
+    meshSet.intersect_withEventCounter(segments, polys, points_raw);
+    logger.getDebugSink()<<"copy only valid intersection points";
+    points.reserve(points_raw.size());
+    for (size_t i = 0; i < points_raw.size(); i++)
+    {
+        if (!polys[i])
+            continue;
+        points.push_back(points_raw[i]);
+    }
+    logger.getDebugSink()<<"make set of unique polygons, i.e. "
+                         <<"consider every polygon only ones";
+    set<const AbstractPolygon*> polySet(polys.begin(), polys.end());
+    size_t size = polySet.size();
+    logger.getDebugSink()<<"reserve event vectors, "<<size;
+    meshIds.reserve(size);
+    polyIds.reserve(size);
+    polyEvents.reserve(size);
+    logger.getDebugSink()<<"copy polygon events to output vectors";
+    set<const AbstractPolygon*>::const_iterator it;
+    for (it = polySet.begin(); it != polySet.end(); it++)
+    {
+        const AbstractPolygon *p = *it;
+        if (!p)
+            continue;
+        const SurfaceMesh *m = meshSet.findComponent(p);
+        meshIds.push_back(m->getId());
+        polyIds.push_back(p->getId());
+        polyEvents.push_back(p->getEventCounter());
+    }
+    logger.getDebugSink()<<"copy mesh events to output vector";
+    meshEvents.resize(meshSet.getNumItems());
+    for (size_t i = 0; i < meshSet.getNumItems(); i++)
+        meshEvents[i] = meshSet.getItems()[i]->getEventCounter();
+}
+
+void MeshSrvBase::intersectMeshPhiPlane(double phi,
+                                        const SurfaceMeshSet &meshSet,
+                                        vector<vector<Point3D> > &points,
+                                        vector<size_t> &outMeshIds,
+                                        vector<size_t> &outPolyIds)
+{
+    logger.getInfoSink()<<"service function "<<__FUNCTION__;
+    points.resize(0);
+    outMeshIds.resize(0);
+    outPolyIds.resize(0);
+    //if (checkContainerEmpty(mesh, "surface mesh"))
+    //{
+        //logger.getInfoSink()<<"empty input, no processing required";
+        //return;
+    //}
+    logger.getDebugSink()<<"prepare plane";
+    phi = fmod(phi, 2.0*M_PI);
+    phi = phi >= 0 ? phi : phi + 2.0*M_PI;
+    Plane plane;
+    Point3D p;
+    p[0] = 0; p[1] = 0; p[2] = 0;
+    plane.setPoint(p);
+    Vector3D normal;
+    normal[0] = -sin(phi);
+    normal[1] = cos(phi);
+    normal[2] = 0;
+    plane.setNormal(normal);
+    logger.getDebugSink()<<"plane "<<plane;
+    size_t s = meshSet.getNumPolygons();
+    logger.getDebugSink()<<"reserve output vectors for "
+                         <<s<<" polygons";
+    points.reserve(s);
+    outMeshIds.reserve(s);
+    outPolyIds.reserve(s);
+    logger.getDebugSink()<<"iterate over polygons";
+    for (size_t i = 0; i < meshSet.getNumItems(); i++)
+    {
+        const SurfaceMesh &m = *meshSet.getItems()[i];
+        for (size_t j = 0; j < m.getNumItems(); j++)
+        {
+            vector<Point3D> r;
+            if (m.getItems()[j]->intersect(plane, r))
+            {
+                double p = phi;
+                if (fabs(r[0][1]) + fabs(r[0][0]) > 0)
+                    p = atan2(r[0][1], r[0][0]);
+                p = p >= 0 ? p : p + 2.0*M_PI;
+                if (fabs(p-phi) > 1e-2)
+                    continue;
+                points.push_back(r);
+                outMeshIds.push_back(m.getId());
+                outPolyIds.push_back(m.getItems()[j]->getId());
+            }
+        }
+    }
+}
+
+void MeshSrvBase::intersectMeshPlane(const Plane &plane,
+                                     const SurfaceMeshSet &meshSet,
+                                     vector<vector<Point3D> > &points,
+                                     vector<size_t> &outMeshIds,
+                                     vector<size_t> &outPolyIds)
+{
+    logger.getInfoSink()<<"service function "<<__FUNCTION__;
+    points.resize(0);
+    outMeshIds.resize(0);
+    outPolyIds.resize(0);
+    //if (checkContainerEmpty(mesh, "surface mesh"))
+    //{
+        //logger.getInfoSink()<<"empty input, no processing required";
+        //return;
+    //}
+    size_t s = meshSet.getNumPolygons();
+    logger.getDebugSink()<<"reserve output vectors for "
+                         <<s<<" polygons";
+    points.reserve(s);
+    outMeshIds.reserve(s);
+    outPolyIds.reserve(s);
+    logger.getDebugSink()<<"iterate over polygons";
+    for (size_t i = 0; i < meshSet.getNumItems(); i++)
+    {
+        const SurfaceMesh &m = *meshSet.getItems()[i];
+        for (size_t j = 0; j < m.getNumItems(); j++)
+        {
+            vector<Point3D> r;
+            if (m.getItems()[j]->intersect(plane, r))
+            {
+                points.push_back(r);
+                outMeshIds.push_back(m.getId());
+                outPolyIds.push_back(m.getItems()[j]->getId());
+            }
+        }
+    }
+}
+
+void MeshSrvBase::rotateMeshToroidally(const SurfaceMesh &inMesh,
+                                       double angle,
+                                       SurfaceMesh &outMesh)
+{
+    logger.getInfoSink()<<"service function "<<__FUNCTION__;
+    if (angle == 0)
+    {
+        logger.getInfoSink()<<"zero rotation angle, no processing";
+        outMesh = inMesh;
+        return;
+    }
+    logger.getDebugSink()<<"create transformation";
+    Transformation trans;
+    Vector3D axis;
+    axis[0] = 0; axis[1] = 0; axis[2] = 1.0;
+    trans.makeRotation(axis, angle);
+    transformMesh(inMesh, trans, outMesh);
+}
+void MeshSrvBase::transformMesh(const SurfaceMesh &inMesh,
+                                const Transformation &trans,
+                                SurfaceMesh &outMesh)
+{
+    logger.getInfoSink()<<"service function "<<__FUNCTION__;
+    if (checkContainerEmpty(inMesh, "surface mesh"))
+    {
+        logger.getInfoSink()<<"empty input, no processing required";
+        outMesh.clear();
+        return;
+    }
+    logger.getDebugSink()<<"copy input to output , size "<<inMesh.getNumItems();
+    outMesh = inMesh;
+    logger.getInfoSink()<<"apply transformation";
+    outMesh.transform(trans);
+}
+
+void MeshSrvBase::rotatePointsToroidally(const vector<Point3D> &points,
+                                         double angle,
+                                         vector<Point3D> &outPoints)
+{
+    logger.getInfoSink()<<"service function "<<__FUNCTION__;
+    if (angle == 0)
+    {
+        logger.getInfoSink()<<"zero rotation angle, no processing";
+        outPoints = points;
+        return;
+    }
+    logger.getDebugSink()<<"create transformation";
+    Transformation trans;
+    Vector3D axis;
+    axis[0] = 0; axis[1] = 0; axis[2] = 1.0;
+    trans.makeRotation(axis, angle);
+    transformPoints(points, trans, outPoints);
+}
+
+
+void MeshSrvBase::transformPoints(const vector<Point3D> &points,
+                                  const Transformation &trans,
+                                  vector<Point3D> &outPoints)
+{
+    logger.getInfoSink()<<"service function "<<__FUNCTION__;
+    if (checkVectorEmpty(points, "input points"))
+    {
+        logger.getInfoSink()<<"empty input, no processing required";
+        outPoints.resize(0);
+        return;
+    }
+    logger.getDebugSink()<<"copy input to output , size "<<points.size();
+    outPoints = points;
+    logger.getDebugSink()<<"iterate and apply transformation";
+    for (size_t i = 0; i < outPoints.size(); i++)
+        trans.apply(outPoints[i]);
+}
+
+void MeshSrvBase::getContainingPolygons(const vector<Point3D> &points,
+                                        const SurfaceMeshSet &meshSet,
+                                        double tolerance,
+                                        vector<vector<size_t> > &meshIds,
+                                        vector<vector<size_t> > &polyIds)
+{
+    logger.getInfoSink()<<"service function "<<__FUNCTION__;
+    if (tolerance <= 0)
+    {
+        logger.getErrorSink()<<"tolerance <= 0 given: "
+                              <<tolerance;
+        throw meshsrvwrap::ArgumentError("tolerance <= 0"
+                                         "given");
+    }
+    if (checkContainerEmpty(meshSet, "surface mesh set") ||
+        checkVectorEmpty(points, "input points"))
+    {
+        logger.getInfoSink()<<"empty input, no processing required";
+        meshIds.resize(0);
+        polyIds.resize(0);
+        return;
+    }
+    logger.getDebugSink()<<"resize output ids vector, size "
+                         << points.size();
+    meshIds.resize(points.size());
+    polyIds.resize(points.size());
+    logger.getDebugSink()<<"iterate over "<<points.size()
+                         <<" points and get containing polygons";
+    const vector<SurfaceMesh *> &meshes = meshSet.getItems();
+    for (size_t i = 0; i < points.size(); i++)
+    {
+        for (size_t j = 0; j < meshes.size(); j++)
+        {
+            vector<const AbstractPolygon *> r;
+            meshes[j]->getContainingPolygons(points[i],
+                                            tolerance, r);
+            meshIds[i].reserve(meshIds[i].size() + r.size());
+            polyIds[i].reserve(polyIds[i].size() + r.size());
+            for (size_t k = 0; k < r.size(); k++)
+            {
+                meshIds[i].push_back(meshes[j]->getId());
+                polyIds[i].push_back(r[k]->getId());
+            }
+        }
+    }
+}
+
+void MeshSrvBase::getPointMeshDistances(const vector<Point3D> &points,
+                                        const SurfaceMesh &mesh,
+                                        vector<double> &distances)
+{
+    logger.getInfoSink()<<"service function "<<__FUNCTION__;
+    if (checkContainerEmpty(mesh, "surface mesh") ||
+        checkVectorEmpty(points, "input points"))
+    {
+        logger.getInfoSink()<<"empty input, no processing required";
+        distances.resize(0);
+        return;
+    }
+    logger.getDebugSink()<<"resize output distances vector, size "
+                         << points.size();
+    distances.resize(points.size());
+    logger.getDebugSink()<<"iterate over "<<points.size()
+                         <<" points and measure distance ";
+    for (size_t i = 0; i < points.size(); i++)
+        distances[i] = mesh.getMinDistance(points[i]).first;
+}
+
+void MeshSrvBase::getClosestMeshPolygons(const vector<Point3D> &points,
+                                         const SurfaceMesh &mesh,
+                                         vector<size_t> &outIds)
+{
+    logger.getInfoSink()<<"service function "<<__FUNCTION__;
+    if (checkContainerEmpty(mesh, "surface mesh") ||
+        checkVectorEmpty(points, "input points"))
+    {
+        logger.getInfoSink()<<"empty input, no processing required";
+        outIds.resize(0);
+        return;
+    }
+    logger.getDebugSink()<<"resize output ids vector, size "
+                         << points.size();
+    outIds.resize(points.size());
+    logger.getDebugSink()<<"iterate over "<<points.size()
+                         <<" points and measure distance ";
+    for (size_t i = 0; i < points.size(); i++)
+        outIds[i] = mesh.getMinDistance(points[i]).second->getId();
+}
+
+void MeshSrvBase::getPointPolygonDistances(const vector<Point3D> &points,
+                                           const vector<size_t> &polygonIds,
+                                           const SurfaceMesh &mesh,
+                                           vector<double> &distances)
+{
+    logger.getInfoSink()<<"service function "<<__FUNCTION__;
+    if (checkContainerEmpty(mesh, "surface mesh") ||
+        checkVectorEmpty(points, "input points") ||
+        checkVectorEmpty(polygonIds, "polygon ids"))
+    {
+        logger.getInfoSink()<<"empty input, no processing required";
+        distances.resize(0);
+        return;
+    }
+    logger.getDebugSink()<<"get polygons by their ids";
+    vector<AbstractPolygon*> polys;
+    mesh.getByIds(polygonIds, polys);
+    logger.getDebugSink()<<"reserve output distances vector, size "
+                         << points.size() * polys.size();
+    distances.resize(0);
+    distances.reserve(points.size() * polys.size());
+    logger.getDebugSink()<<"iterate over "<<points.size()
+                         <<" points and measure distance "
+                         <<"to "<<polys.size()<<" polygons";
+    for (size_t i = 0; i < points.size(); i++)
+        for (size_t j = 0; j < polys.size(); j++)
+            distances.push_back(polys[j]->getDistance(points[i]));
+}
+void MeshSrvBase::getClosestPolygons(const vector<Point3D> &points,
+                                     const SurfaceMeshSet &meshSet,
+                                     vector<size_t> &meshIds,
+                                     vector<size_t> &polyIds)
+{
+    logger.getInfoSink()<<"service function "<<__FUNCTION__;
+    if (checkContainerEmpty(meshSet, "surface mesh set") ||
+        checkVectorEmpty(points, "input points"))
+    {
+        logger.getInfoSink()<<"empty input, no processing required";
+        meshIds.resize(0);
+        polyIds.resize(0);
+        return;
+    }
+    logger.getDebugSink()<<"find any non zero polygon";
+    const vector<meshlib::SurfaceMesh*> &meshes = meshSet.get();
+    //find first non-zero polygon
+    AbstractPolygon *poly0 = 0;
+    for (size_t i = 0; i < meshes.size(); i++)
+    {
+        for (size_t j = 0; j < meshes[i]->getNumItems(); j++)
+        {
+            if (meshes[i]->getItems()[j])
+            {
+                poly0 = meshes[i]->getItems()[j];
+                meshIds.resize(points.size(), meshes[i]->getId());
+                polyIds.resize(points.size(), poly0->getId());
+                break;
+            }
+        }
+        if (poly0)
+            break;
+    }
+    if (!poly0)
+    {
+        logger.getInfoSink()<<"no polygons in the set";
+        meshIds.resize(0);
+        polyIds.resize(0);
+        return;
+    }
+
+    logger.getDebugSink()<<"iterate over "
+                         <<points.size()
+                         <<" points and"
+                         <<meshes.size()
+                         <<" meshes and find distances";
+    for (size_t i = 0; i < points.size(); i++)
+    {
+        double min_dist = poly0->getDistance(points[i]);
+
+        for (size_t j = 0; j < meshes.size(); j++)
+        {
+            pair<double, const AbstractPolygon*> p =
+                                         meshes[j]->getMinDistance(points[i]);
+            if (p.second and p.first < min_dist)
+            {
+                min_dist = p.first;
+                meshIds[i] = meshes[j]->getId();
+                polyIds[i] = p.second->getId();
+            }
+        }
+    }
+}
+
+
+void MeshSrvBase::getUniformRandomPoints(size_t numPoints,
+                                         const SurfaceMesh &mesh,
+                                         vector<Point3D> &points)
+{
+    logger.getInfoSink()<<"service function "<<__FUNCTION__;
+    if (checkContainerEmpty(mesh, "surface mesh") || numPoints == 0)
+    {
+        logger.getInfoSink()<<"empty input, no processing required";
+        points.resize(0);
+        return;
+    }
+    RandomGenerator generator;
+    mesh.getUniformRandomPoints(generator, numPoints, points);
+}
+
+void MeshSrvBase::getRandomPointsForPolygon(size_t numPoints,
+                                            const vector<size_t> &polygonIds,
+                                            const SurfaceMesh &mesh,
+                                            vector<Point3D> &points)
+{
+    logger.getInfoSink()<<"service function "<<__FUNCTION__;
+    if (checkContainerEmpty(mesh, "surface mesh") ||
+        checkVectorEmpty(polygonIds, "polygon ids") ||
+        numPoints == 0)
+    {
+        logger.getInfoSink()<<"empty input, no processing required";
+        points.resize(0);
+        return;
+    }
+    logger.getDebugSink()<<"get polygons by their ids";
+    vector<AbstractPolygon*> polys;
+    mesh.getByIds(polygonIds, polys);
+    logger.getDebugSink()<<"reserve output points vector, size "
+                         << numPoints * polys.size();
+    points.resize(0);
+    points.reserve(numPoints * polys.size());
+    logger.getDebugSink()<<"iterate over "<<polys.size()
+                         <<" polygons and generate points";
+    RandomGenerator generator;
+    for (size_t i = 0; i < polys.size(); i++)
+    {
+        vector<Point3D> r;
+        polys[i]->getRandomPoints(generator, numPoints, r);
+        for (size_t j = 0; j < r.size(); j++)
+            points.push_back(r[j]);
+    }
+}
+
+//void dropDegeneratedPolygons(const SurfaceMesh &inMesh,
+                             //SurfaceMesh &outMesh)
+//{
+    //logger.getInfoSink()<<"service function "<<__FUNCTION__;
+    //if (checkContainerEmpty(inMesh, "input surface mesh"))
+    //{
+        //logger.getInfoSink()<<"empty input, no processing required";
+        //outMesh.clear();
+        //return;
+    //}
+    //logger.getDebugSink()<<"refine "<<inMesh.getNumItems()
+                       //<<" polygons to "<<threshold <<" and set to the output";
+    //outMesh.transfer(*inMesh.refineMesh(threshold));
+//}
+
+void MeshSrvBase::refineMesh(const SurfaceMesh &inMesh,
+                             double threshold,
+                             SurfaceMesh &outMesh)
+{
+    logger.getInfoSink()<<"service function "<<__FUNCTION__;
+    if (threshold <= 0)
+    {
+        logger.getErrorSink()<<"threshold <= 0 given: "
+                              <<threshold;
+        throw meshsrvwrap::ArgumentError("threshold <= 0"
+                                         "given");
+    }
+    if (checkContainerEmpty(inMesh, "input surface mesh"))
+    {
+        logger.getInfoSink()<<"empty input, no processing required";
+        outMesh.clear();
+        return;
+    }
+    logger.getDebugSink()<<"refine "<<inMesh.getNumItems()
+                       <<" polygons to "<<threshold <<" and set to the output";
+    outMesh.transfer(*inMesh.refineMesh(threshold));
+}
+
+void MeshSrvBase::triangulateMesh(const SurfaceMesh &inMesh,
+                                  SurfaceMesh &outMesh)
+{
+    logger.getInfoSink()<<"service function "<<__FUNCTION__;
+    if (checkContainerEmpty(inMesh, "input surface mesh"))
+    {
+        logger.getInfoSink()<<"empty input, no processing required";
+        outMesh.clear();
+        return;
+    }
+    logger.getDebugSink()<<"triangulate and set to the output";
+    outMesh.transfer(*inMesh.triangulate());
+}
+
+void MeshSrvBase::combineMeshes(const SurfaceMeshSet &meshSet,
+                                SurfaceMesh &mesh)
+{
+    logger.getInfoSink()<<"service function "<<__FUNCTION__;
+    if (checkContainerEmpty(meshSet, "mesh set"))
+    {
+        logger.getInfoSink()<<"empty input, no processing required";
+        mesh.clear();
+        return;
+    }
+    logger.getDebugSink()<<"add all meshes from the set, size "
+                         <<meshSet.getNumItems();
+    mesh.add<SurfaceMesh>(meshSet.getItems());
+    logger.getDebugSink()<<"reassign ids to polygons, size "
+                         <<mesh.getNumItems();
+    mesh.assignIncrementalIds();
+}
+
+void MeshSrvBase::getPolygonNormals(const vector<size_t> &polygonIds,
+                                    const SurfaceMesh &mesh,
+                                    vector<Vector3D> &normals)
+{
+    logger.getInfoSink()<<"service function "<<__FUNCTION__;
+    if (checkContainerEmpty(mesh, "surface mesh") ||
+        checkVectorEmpty(polygonIds, "polygon ids"))
+    {
+        logger.getInfoSink()<<"empty input, no processing required";
+        normals.resize(0);
+        return;
+    }
+    logger.getDebugSink()<<"get polygons by their ids";
+    vector<AbstractPolygon*> polys;
+    mesh.getByIds(polygonIds, polys);
+    logger.getDebugSink()<<"resize output normals vector";
+    normals.resize(polys.size());
+    logger.getDebugSink()<<"iterate over "<<polys.size()<<" polygons "
+                                        <<"and get their normal vectors";
+    for (size_t i = 0; i < polys.size(); i++)
+        normals[i] = polys[i]->getNormal();
+}
+
+void MeshSrvBase::getPolygonCenters(const vector<size_t> &polygonIds,
+                                    const SurfaceMesh &mesh,
+                                    double relTol, double absTol,
+                                    vector<Vector3D> &centers)
+{
+    logger.getInfoSink()<<"service function "<<__FUNCTION__;
+    if (checkContainerEmpty(mesh, "surface mesh") ||
+        checkVectorEmpty(polygonIds, "polygon ids"))
+    {
+        logger.getInfoSink()<<"empty input, no processing required";
+        centers.resize(0);
+        return;
+    }
+    logger.getDebugSink()<<"get polygons by their ids";
+    vector<AbstractPolygon*> polys;
+    mesh.getByIds(polygonIds, polys);
+    logger.getDebugSink()<<"resize output centers vector";
+    centers.resize(polys.size());
+    logger.getDebugSink()<<"iterate over "<<polys.size()<<" polygons "
+                                        <<"and get their centers";
+    for (size_t i = 0; i < polys.size(); i++)
+    {
+        polys[i]->getSurfaceIntegral_R(relTol, absTol, centers[i]);
+        double area = polys[i]->getArea();
+        if (area == 0)
+        {
+            logger.getErrorSink()<<"zero area polygon "
+                <<std::hex<<polys[i]<<" division impossible";
+            throw invalid_argument("division by 0 - zero area polygon");
+        }
+        centers[i] /= area;
+    }
+}
+void MeshSrvBase::getPolygonAreas(const vector<size_t> &polygonIds,
+                                  const SurfaceMesh &mesh,
+                                  vector<double> &areas)
+{
+    logger.getInfoSink()<<"service function "<<__FUNCTION__;
+    if (checkContainerEmpty(mesh, "surface mesh") ||
+        checkVectorEmpty(polygonIds, "polygon ids"))
+    {
+        logger.getInfoSink()<<"empty input, no processing required";
+        areas.resize(0);
+        return;
+    }
+    logger.getDebugSink()<<"get polygons by their ids";
+    vector<AbstractPolygon*> polys;
+    mesh.getByIds(polygonIds, polys);
+    logger.getDebugSink()<<"resize output areas vector";
+    areas.resize(polys.size());
+    logger.getDebugSink()<<"iterate over "<<polys.size()<<" polygons "
+                                        <<"and get their areas";
+    for (size_t i = 0; i < polys.size(); i++)
+        areas[i] = polys[i]->getArea();
+}
+
+void MeshSrvBase::getMeshArea(const SurfaceMesh &mesh,
+                              double &area)
+{
+    logger.getInfoSink()<<"service function "<<__FUNCTION__;
+    if (checkContainerEmpty(mesh, "surface mesh"))
+    {
+        logger.getInfoSink()<<"empty input, no processing required";
+        area = 0;
+        return;
+    }
+    logger.getDebugSink()<<"get mesh area";
+    area = mesh.getArea();
+}
+
+void MeshSrvBase::getBuildInfo(string& info)
+{
+    logger.getInfoSink()<<"service function "<<__FUNCTION__;
+
+    ostringstream strm;
+
+    strm<<"version:\t"<<VERSION<<"\n";
+    strm<<"build time "<<__DATE__<<" "<<__TIME__<<endl;
+    strm<<"limits:"<<endl;
+    strm<<"\tabsolute flat quadrangle tolerance:\t"<<PLANE_ABS_EPS<<endl;
+    strm<<"\trelative flat quadrangle tolerance:\t"<<PLANE_REL_EPS<<endl;
+    strm<<"have thread support (Klubok):\t";
+#ifdef HAVE_KLUBOK
+    strm<<"yes";
+    strm<<endl;
+    strm<<"number of threads:\t"<<PROCESSOR_COUNT<<endl;
+#else
+    strm<<"no";
+    strm<<endl;
+#endif      // -----  HAVE_KLUBOK
+    strm<<"random generator\t";
+#ifdef HAVE_GSL
+    strm<<"GSL Mersenne twister\n";
+#else
+    strm<<"C++ standard\n"
+#endif  /* end of HAVE_GSL */
+    strm<<"default components database:\n";
+    strm<<"\tThrift\n";
+    strm<<"\t"<<DEFAULT_THRIFT_DBHOST
+        <<":"<<DEFAULT_THRIFT_DBPORT<<"\n";
+    strm<<"supported db protocols:\n"
+        <<"\tThrift\n";
+    strm<<"cache path: "<<CMP_CACHE_PATH<<"\n";
+
+    info = strm.str();
+}
+
+void MeshSrvBase::getPolyhedronSurfaceAreas(const vector<size_t> &polyhedronIds,
+                                            const VolumeMesh &mesh,
+                                            vector<double> &areas)
+{
+    logger.getInfoSink()<<"service function "<<__FUNCTION__;
+    if (checkContainerEmpty(mesh, "volume mesh") ||
+        checkVectorEmpty(polyhedronIds, "polyhedron ids"))
+    {
+        logger.getInfoSink()<<"empty input, no processing required";
+        areas.resize(0);
+        return;
+    }
+    logger.getDebugSink()<<"get polyhedrons by their ids";
+    vector<Polyhedron*> polys;
+    mesh.getByIds(polyhedronIds, polys);
+    logger.getDebugSink()<<"resize output areas vector";
+    areas.resize(polys.size());
+    logger.getDebugSink()<<"iterate over "<<polys.size()<<" polyhedrons "
+                                        <<"and get their areas";
+    for (size_t i = 0; i < polys.size(); i++)
+        areas[i] = polys[i]->getSurfaceMesh().getArea();
+}
+
+void MeshSrvBase::getPolyhedronVolumes(const vector<size_t> &polyhedronIds,
+                                       const VolumeMesh &mesh,
+                                       vector<double> &volumes)
+{
+    logger.getInfoSink()<<"service function "<<__FUNCTION__;
+    if (checkContainerEmpty(mesh, "volume mesh") ||
+        checkVectorEmpty(polyhedronIds, "polyhedron ids"))
+    {
+        logger.getInfoSink()<<"empty input, no processing required";
+        volumes.resize(0);
+        return;
+    }
+    logger.getDebugSink()<<"get polyhedrons by their ids";
+    vector<Polyhedron*> polys;
+    mesh.getByIds(polyhedronIds, polys);
+    logger.getDebugSink()<<"resize output volumes vector";
+    volumes.resize(polys.size());
+    logger.getDebugSink()<<"iterate over "<<polys.size()<<" polyhedrons "
+                                        <<"and get their volumes";
+    for (size_t i = 0; i < polys.size(); i++)
+        volumes[i] = polys[i]->getVolume();
+}
+
+void MeshSrvBase::getPolyhedronCenters(const vector<size_t> &polyhedronIds,
+                                       const VolumeMesh &mesh,
+                                       vector<Vector3D> &centers)
+{
+    logger.getInfoSink()<<"service function "<<__FUNCTION__;
+    if (checkContainerEmpty(mesh, "volume mesh") ||
+        checkVectorEmpty(polyhedronIds,
+                                                 "polyhedron ids"))
+    {
+        logger.getInfoSink()<<"empty input, no processing required";
+        centers.resize(0);
+        return;
+    }
+    logger.getDebugSink()<<"get polyhedrons by their ids";
+    vector<Polyhedron*> polys;
+    mesh.getByIds(polyhedronIds, polys);
+    logger.getDebugSink()<<"resize output centers vector";
+    centers.resize(polys.size());
+    logger.getDebugSink()<<"iterate over "<<polys.size()<<" polyhedrons "
+                                        <<"and get their centers";
+    for (size_t i = 0; i < polys.size(); i++)
+        centers[i] = polys[i]->getCenter().getCoordinates();
+}
+
+void MeshSrvBase::getMeshVolume(const VolumeMesh &mesh,
+                                double &volume)
+{
+    logger.getInfoSink()<<"service function "<<__FUNCTION__;
+    if (checkContainerEmpty(mesh, "volume mesh"))
+    {
+        logger.getInfoSink()<<"empty input, no processing required";
+        volume = 0;
+        return;
+    }
+    logger.getDebugSink()<<"get mesh volume";
+    volume = mesh.getVolume();
+}

service/base/MeshSrvBase.h

+// MeshSrvBase.cpp - base server class, part of MeshLib.
+// Copyright 2013 Sergey Bozhenkov, boz at ipp.mpg.de
+// Licensed under GPLv3 or later, see the COPYING file.
+#ifndef MESHSRVBASE_JP3C62R
+#define MESHSRVBASE_JP3C62R
+
+#include "ContainerOfIdItems.h"
+#include "Point3D.h"
+#include <ctime>
+#include <LinAlg/Vector3D.h>
+#include <Slog/Logger.h>
+#include <vector>
+#include <string>
+
+namespace meshlib
+{ 
+    class Plane;
+    class Segment;
+    class SurfaceMesh;
+    class SurfaceMeshSet;
+    class VolumeMesh;
+} //namespace meshlib
+
+namespace meshsrvbase
+{
+    using slog::Logger;
+    using std::vector;
+    using std::string;
+    using meshlib::ContainerOfIdItems;
+    
+    // =========================================================================
+    /// @brief Base server class, provides all operations but in
+    /// terms of native library types.
+    // =========================================================================
+    class MeshSrvBase
+    {
+        public:
+            MeshSrvBase() : logger(Logger::getLogger()) {};
+            ~MeshSrvBase(){};
+            
+            //void dropDegeneratedPolygons(const meshlib::SurfaceMesh &inMesh,
+                                         //meshlib::SurfaceMesh &outMesh);
+            void refineMesh(const meshlib::SurfaceMesh &inMesh,
+                            double threshold,
+                            meshlib::SurfaceMesh &outMesh);
+            void triangulateMesh(const meshlib::SurfaceMesh &inMesh,
+                                 meshlib::SurfaceMesh &outMesh);
+            void combineMeshes(const meshlib::SurfaceMeshSet &meshSet,
+                               meshlib::SurfaceMesh &mesh);
+            void getPolygonNormals(const vector<size_t> &polygonIds,
+                                   const meshlib::SurfaceMesh &mesh,
+                                   vector<linalg::Vector3D> &normals);
+            void getPolygonCenters(const vector<size_t> &polygonIds,
+                                   const meshlib::SurfaceMesh &mesh,
+                                   double relTol, double absTol,
+                                   vector<linalg::Vector3D> &centers);
+            void getPolygonAreas(const vector<size_t> &polygonIds,
+                                 const meshlib::SurfaceMesh &mesh,
+                                 vector<double> &areas);
+            void getMeshArea(const meshlib::SurfaceMesh &mesh,
+                             double &area);
+            void getPointPolygonDistances(const vector<meshlib::Point3D> &points,
+                                          const vector<size_t> &polygonIds,
+                                          const meshlib::SurfaceMesh &mesh,
+                                          vector<double> &distances);
+            void getClosestPolygons(const vector<meshlib::Point3D> &points,
+                                    const meshlib::SurfaceMeshSet &meshSet,
+                                    vector<size_t> &meshIds,
+                                    vector<size_t> &polyIds);
+            void getPointMeshDistances(const vector<meshlib::Point3D> &points,
+                                       const meshlib::SurfaceMesh &mesh,
+                                       vector<double> &distances);
+            void getClosestMeshPolygons(const vector<meshlib::Point3D> &points,
+                                        const meshlib::SurfaceMesh &mesh,
+                                        vector<size_t> &outIds);
+            void getContainingPolygons(const vector<meshlib::Point3D> &points,
+                                       const meshlib::SurfaceMeshSet &meshSet,
+                                       double tolerance,
+                                       vector<vector<size_t> > &meshIds,
+                                       vector<vector<size_t> > &polyIds);
+
+            void getPolyhedronCenters(const vector<size_t> &polyhedronIds,
+                                      const meshlib::VolumeMesh &mesh,
+                                      vector<linalg::Vector3D> &centers);
+            void getPolyhedronSurfaceAreas(const vector<size_t> &polyhedronIds,
+                                           const meshlib::VolumeMesh &mesh,
+                                           vector<double> &areas);
+            void getPolyhedronVolumes(const vector<size_t> &polyhedronIds,
+                                      const meshlib::VolumeMesh &mesh,
+                                      vector<double> &volumes);
+            void getMeshVolume(const meshlib::VolumeMesh &mesh,
+                               double &volume);
+
+            void getUniformRandomPoints(size_t numPoints,
+                                        const meshlib::SurfaceMesh &mesh,
+                                        vector<meshlib::Point3D> &points);
+            void getRandomPointsForPolygon(size_t numPoints,
+                                           const vector<size_t> &polygonIds,
+                                           const meshlib::SurfaceMesh &mesh,
+                                           vector<meshlib::Point3D> &points);
+
+            void transformPoints(const vector<meshlib::Point3D> &points,
+                                 const meshlib::Transformation &trans,
+                                 vector<meshlib::Point3D> &outPoints);
+            void rotatePointsToroidally(const vector<meshlib::Point3D> &points,
+                                        double angle,
+                                        vector<meshlib::Point3D> &outPoints);
+            void transformMesh(const meshlib::SurfaceMesh &inMesh,
+                               const meshlib::Transformation &trans,
+                               meshlib::SurfaceMesh &outMesh);
+            void rotateMeshToroidally(const meshlib::SurfaceMesh &inMesh,
+                                      double angle,
+                                      meshlib::SurfaceMesh &outMesh);
+            void intersectMeshPlane(const meshlib::Plane &plane,
+                                    const meshlib::SurfaceMeshSet &mesh,
+                                    vector<vector<meshlib::Point3D> > &points,
+                                    vector<size_t> &outMeshIds,
+                                    vector<size_t> &outPolyIds);
+            void intersectMeshPhiPlane(double phi,
+                                       const meshlib::SurfaceMeshSet &mesh,
+                                       vector<vector<meshlib::Point3D> > &points,
+                                       vector<size_t> &outMeshIds,
+                                       vector<size_t> &outPolyIds);
+            void intersectSegmentMesh(const vector<meshlib::Segment> &segments,
+                                      meshlib::SurfaceMeshSet &meshSet,
+                                      vector<meshlib::Point3D> &points,
+                                      vector<size_t> &meshIds,
+                                      vector<size_t> &polyIds,
+                                      vector<size_t> &polyEvents,
+                                      vector<size_t> &meshEvents);
+    
+            void getBuildInfo(string& info);
+            time_t getTimeStamp() { return time(0);};
+
+        protected:
+            Logger &logger;
+            template <class T>
+            bool checkContainerEmpty(const ContainerOfIdItems<T> &mesh,
+                                     const string &contName) const;
+            template <class T>
+            bool checkVectorEmpty(const vector<T> &vec,
+                                  const string &vecName) const;
+    };
+    //
+    // =========================================================================
+    /// @brief Check if vector is empty, use vector name to log the result.
+    // =========================================================================
+    template <class T>
+    bool MeshSrvBase::checkVectorEmpty(const vector<T> &vec,
+                                       const string &vecName) const
+    {
+        if (vec.empty())
+        {
+            logger.getDebugSink()<<"empty vector "<<vecName;
+            return true;
+        }
+        return false;
+    }
+
+    template <class T>
+    bool MeshSrvBase::checkContainerEmpty(const ContainerOfIdItems<T> &cont,
+                                          const string &contName) const
+    {
+        if (cont.getNumItems() == 0)
+        {
+            logger.getDebugSink()<<"empty "<<contName;
+            return true;
+        }
+        return false;
+    }
+} //namespace meshsrv
+#endif /* end of include guard: MESHSRVBASE_JP3C62R */

service/base/README

+Base classes for all flavours of services. They implement the operations
+in terms of the library types.
+You might want to change settings in srvconfig.h

service/base/srvconfig.h

+// srvconfig.h -service  config, part of MeshLib.
+// Copyright 2014 Sergey Bozhenkov, boz at ipp.mpg.de
+// Licensed under GPLv3 or later, see the COPYING file.
+#ifndef SRVONFIG_H_8AWXOUQT
+#define SRVONFIG_H_8AWXOUQT
+namespace meshsrv
+{
+#define HAVE_THRIFT 1
+#define DEFAULT_THRIFT_DBHOST "lxpowerboz"
+#define DEFAULT_THRIFT_DBPORT 9091
+#define CMP_CACHE_PATH ".cache"
+} //namespace meshsrv
+#endif /* end of include guard: SRVONFIG_H_8AWXOUQT */

service/clients/matlab-axis/Makefile

+####### Compiler, tools and options
+
+JAR			  = /usr/bin/jar -cvf
+JAVAC 		  = /usr/bin/javac
+JAVA		  = /usr/bin/java
+WSDL2J		  = org.apache.axis.wsdl.WSDL2Java
+CLASSPATH	  = "/usr/share/java/axis.jar:\
+				/usr/share/java/commons-discovery.jar:\
+				/usr/share/java/commons-logging.jar:\
+				/usr/share/java/jaxrpc.jar:\
+				/usr/share/java/saaj.jar:\
+				/usr/share/java/xercesImpl.jar:\
+				/usr/share/java/xml-apis.jar:\
+				/usr/share/java/log4j-1.2.jar:\
+				/usr/share/java/wsdl4j.jar:\
+				/usr/share/java/axis/axis.jar:\
+				/usr/share/java/axis/jaxrpc.jar:\
+				/usr/share/java/axis/saaj.jar:\
+				./"
+PATH 		  = $(subst : ,:,$(CLASSPATH))
+WSDL		  = "http://lxpowerboz:88/services/cpp/RayCross?wsdl"
+DEL			  = /bin/rm -rvf
+
+####### Files
+
+PREFIX		  = de/mpg/ipp/hgw/boz/gsoap/raycross/
+SOURCES       = $(PREFIX)RayCrossServiceStub.java \
+				$(PREFIX)RayCrossServicePortType.java \
+				$(PREFIX)RayCrossService.java \
+				$(PREFIX)RayCrossServiceLocator.java \
+				$(PREFIX)CartesianGrid.java \
+				$(PREFIX)Distance.java \
+				$(PREFIX)ElementLoad.java \
+				$(PREFIX)Loads.java \
+				$(PREFIX)Machine.java \
+				$(PREFIX)MeshedModel.java \
+				$(PREFIX)Points3D.java \
+				$(PREFIX)PolygonList.java \
+				$(PREFIX)PolygonPlaneIntersection.java \
+				$(PREFIX)ResultGetAreas.java \
+				$(PREFIX)ResultGetRandomFixN.java \
+				$(PREFIX)ResultIntersection.java
+CLASSES       =  $(subst .java,.class,$(SOURCES))
+DIR			  = de
+JARFILE		  = raycross.jar
+
+####### Implicit rules
+
+%.class: %.java
+	$(JAVAC) -classpath $(PATH) $<
+
+####### Build rules
+
+all: jar
+
+$(CLASSES): $(SOURCES)
+
+$(SOURCES): $(DIR)
+
+$(DIR): Makefile
+	$(JAVA) -cp $(PATH) $(WSDL2J) $(WSDL)
+
+jar: $(CLASSES) Makefile
+	$(JAR) $(JARFILE) ./$(PREFIX)*.class
+
+FORCE:
+
+###### Clean
+clean:
+	$(DEL) $(CLASSFILE) $(TARGET) $(CLASSES) $(SOURCES) $(DIR) $(JARFILE)
+

service/clients/matlab-axis/README

+soap_outdated Java-Axis client to use with matlab.
+
+To build jar file simply run:
+    make

service/conversion/Basic.h

+// Basic.h - Basic class, part of MeshLin.
+// Copyright 2013 Sergey Bozhenkov, boz at ipp.mpg.de
+// Licensed under GPLv3 or later, see the COPYING file.
+#ifndef BASIC_H_WDRK3NBI
+#define BASIC_H_WDRK3NBI
+
+#include <Slog/Logger.h>
+#include <string>
+#include <vector>
+
+namespace meshsrvwrap
+{
+    using std::vector;
+    using std::string;
+    using slog::Logger;
+    // =========================================================================
+    /// @brief Class with static methods for common conversions.
+    // =========================================================================
+    class Basic
+    {
+        public:
+            template <class T>
+            static T copyScalar(T input, double def = 0);
+            template <class T>
+            static T copyScalar(T *input, double def = 0);
+   
+            template <class TIn, class TOut>
+            static void copyVector(const vector<TIn> &input, vector<TOut> &output);
+            template <class TIn, class TOut>
+            static void copyVector(const vector<TIn> *input, vector<TOut> &output);
+ 
+            template <class TIn, class TOut>
+            static void copyVector(const vector<TIn> &input, vector<TOut> **output);
+
+
+            template<class IntType>
+            static long int hash(IntType v) {return static_cast<long int>(v);};
+            static long int hash(float v) {return *((long int*)&v);};
+            static long int hash(double v) {return *((long int*)&v);};
+            static void combineHash(long int &seed, long int v)
+            {
+                //grabbed from boost::hash
+                seed ^= v + 0x9e3779b9 + (seed<<6) + (seed>>2);
+            }
+            template<class Type>
+            static long int hash(const vector<Type > &v)
+            {
+                long int hashcode = 0;
+                for (size_t i = 0; i < v.size(); i++)
+                {
+                    combineHash(hashcode, hash(v[i]));
+                }
+                return hashcode;
+            }
+            static long int hash(const string &s) 
+            {
+                long int hashcode = 0;
+                for (size_t i = 0; i < s.size(); i++)
+                {
+                    combineHash(hashcode, hash(s[i]));
+                }
+                return hashcode;
+            }
+
+
+        private:
+            Basic () {};
+            virtual ~Basic () {};
+    
+    };
+    // =========================================================================
+    /// @brief In pair with pointer method used to do copying in the same
+    /// way  for both cases.
+    // =========================================================================
+    template <class T>
+    T Basic::copyScalar(T input, double def)
+    {
+        (void) def;
+        return input;
+    }
+    // =========================================================================
+    /// @brief In pair with reference method used to do copying in the same
+    /// way  for both cases.
+    // =========================================================================
+    template <class T>
+    T Basic::copyScalar(T *input, double def)
+    {
+        if (input)
+            return *input;
+        else
+            return def;
+    }
+
+    // =========================================================================
+    /// @brief In pair with pointer method used to do copying in the same
+    /// way  for both cases.
+    // =========================================================================
+    template <class TIn, class TOut>
+    void Basic::copyVector(const vector<TIn> &input, vector<TOut> &output)
+    {
+        output.resize(input.size());
+        for (size_t i = 0; i < input.size(); i++)
+            output[i] = static_cast<TOut>(input[i]);
+    }
+    // =========================================================================
+    /// @brief In pair with reference method used to do copying in the same
+    /// way  for both cases.
+    // =========================================================================
+    template <class TIn, class TOut>
+    void Basic::copyVector(const vector<TIn> *input, vector<TOut> &output)
+    {
+        if (input)
+            copyVector(*input, output);
+        else
+            output.clear();
+    }
+    // =========================================================================
+    /// @brief In pair with reference method used to do copying in the same
+    /// way  for both cases.
+    // =========================================================================
+    template <class TIn, class TOut>
+    void Basic::copyVector(const vector<TIn> &input, vector<TOut> **output)
+    {
+        if (!*output)
+            *output = new vector<TOut>;
+        copyVector(*input, **output);
+    }
+
+} //namespace meshsrvwrap
+
+#endif /* end of include guard: BASIC_H_WDRK3NBI */

service/conversion/CachedClient.h

+// CachedClient.h - CachedClient class, part of MeshLib.
+// Copyright 2014 Sergey Bozhenkov, boz at ipp.mpg.de
+// Licensed under GPLv3 or later, see the COPYING file.
+#ifndef CACHEDCLIENT_H_6MJKPL0B
+#define CACHEDCLIENT_H_6MJKPL0B
+
+#include "DataReference.h"
+#include "../thrift/ComponentsDBClient.h"
+#include "../thrift/ComponentsThriftFile.h"
+#include <Slog/Logger.h>
+#include <string>
+#include <vector>
+#include <sstream>
+#include <thrift/protocol/TBinaryProtocol.h>
+#ifdef UNIX
+#include <sys/stat.h>
+#endif  /* end of UNIX */
+
+namespace meshsrvwrap
+{
+    using slog::Logger;
+    using std::vector;
+    using std::string;
+    using std::ostringstream;
+    using apache::thrift::protocol::TBinaryProtocol;
+    // =========================================================================
+    /// @brief For accessing references.
+    // =========================================================================
+    class CachedClient
+    {
+        public:
+            CachedClient (const string &path) : path(path) {makePath();};
+
+            void makePath() const;
+            template<class RefType>
+            void getComponent(const RefType &reference,
+                             vector<componentsdb2::ComponentUnion> &cmps) const;
+            template<class RefType>
+            bool tryCache(time_t cmp_modified, const RefType &ref,
+                          vector<componentsdb2::ComponentUnion> &cmps) const;
+            template<class RefType>
+            void saveToCache(const RefType &reference,
+                             componentsdb2::ComponentUnion &cmp) const;
+            template<class RefType>
+            void getCmpFileName(const RefType &reference,
+                                string &fileName) const;
+             
+        private:
+            string path;
+    };
+    
+    // =========================================================================
+    /// @brief Get component from cache or from client.
+    // =========================================================================
+    template<class RefType>
+    void CachedClient::getComponent(const RefType &ref,
+                             vector<componentsdb2::ComponentUnion> &cmps) const
+    {
+        Logger &logger = Logger::getLogger();
+        logger.getInfoSink()<<"cached access to data reference for mesh";
+        DataReference::checkProtocol(ref);
+        if (ref.protocol == dataref::TCP_THRIFT_FRAMEDBINARY)
+        {
+            meshsrv::ComponentsDBClient client =
+                        DataReference::getTCPDB<
+                        meshsrv::ComponentsDBClient>(ref, ref.__isset);
+
+            vector<int> ids(1, client.convertId(ref.dataId));
+
+            time_t cmp_modified = client.getComponentLastModified(ids[0]);
+            if (!tryCache(cmp_modified, ref, cmps))
+            {
+                logger.getInfoSink()<<"fetch "<<ids[0];
+                client.getComponent(ids, cmps);
+                saveToCache(ref, cmps[0]);
+            }
+
+        }
+    }
+    // =========================================================================
+    /// @brief Get cache file name for the component reference.
+    // =========================================================================
+    template<class RefType>
+    void CachedClient::getCmpFileName(const RefType &ref,
+                                      string &fileName) const
+    {
+        long int h = DataReference::hash(ref, ref.__isset);
+        ostringstream strm;
+        strm<<path<<"/cmp_"<<h<<".thrift";
+        fileName = strm.str();
+    }
+
+    // =========================================================================
+    /// @brief Try getting from cache, return true on success.
+    // =========================================================================
+    template<class RefType>
+    bool CachedClient::tryCache(time_t cmp_modified, const RefType &ref,
+                              vector<componentsdb2::ComponentUnion> &cmps) const
+    {
+        Logger &logger = Logger::getLogger();
+        string fileName;
+        getCmpFileName(ref, fileName);
+        logger.getDebugSink()<<"cache file name for component "<<fileName;
+        meshsrv::ComponentsThriftFile<TBinaryProtocol> cacheFile(fileName);
+        time_t cache_modified = cacheFile.getLastModified();
+        logger.getInfoSink()<<"component last modified "<<cmp_modified
+                            <<", cache last modified "<<cache_modified;
+        if (cache_modified > cmp_modified)
+        {
+            logger.getInfoSink()<<"read cached component";
+            dataref::DataReference cache_ref;
+            cmps.resize(1);
+            cacheFile.readFromFile(cache_ref, cmps[0]);
+            if (DataReference::areEqual(ref, ref.__isset,
+                                        cache_ref, cache_ref.__isset))
+            {
+                logger.getInfoSink()<<"reference in cache file coincide with "
+                                    <<"the requested one => use cached data";
+                return true;
+            }
+            else
+                logger.getInfoSink()<<"reference in cache file differs "
+                                    <<"from the requested one => fetch data";
+        }
+        cmps.resize(0);
+        return false;
+    }
+    // =========================================================================
+    /// @brief Save to cache file.
+    // =========================================================================
+    template<class RefType>
+    void CachedClient::saveToCache(const RefType &ref,
+                                   componentsdb2::ComponentUnion &cmp) const
+    {
+        Logger &logger = Logger::getLogger();
+        string fileName;
+        getCmpFileName(ref, fileName);
+        logger.getInfoSink()<<"saving cache file "<<fileName;
+        meshsrv::ComponentsThriftFile<TBinaryProtocol> cacheFile(fileName);
+        dataref::DataReference refThrift;
+        DataReference::makeThriftReference(ref, ref.__isset, refThrift);
+        cacheFile.writeToFile(refThrift, cmp);
+    }
+    // =========================================================================
+    /// @brief Create path if possible, works only for UNIXes.
+    // =========================================================================
+    void CachedClient::makePath() const
+    {
+#ifdef UNIX
+        //try to create directory, will fail and does nothing if exists
+        Logger::getLogger().getInfoSink()<<"creating path "<<path;
+        mkdir(path.c_str(), 0755);
+#else
+        Logger::getLogger().getWarnSink()<<"can not create paths "
+                            <<"on not UNIXes, caching into "<<path<<" may fail";
+#endif  /* end of UNIX */
+    }
+} //namespace meshsrvwrap
+
+#endif /* end of include guard: CACHEDCLIENT_H_6MJKPL0B */
+

service/conversion/DataReference.h

+// DataReference.h - DataReference class, part of MeshLib.
+// Copyright 2013 Sergey Bozhenkov, boz at ipp.mpg.de
+// Licensed under GPLv3 or later, see the COPYING file.
+#ifndef DATAREFERENCE_H_2QNJR3X8
+#define DATAREFERENCE_H_2QNJR3X8
+
+#include "Basic.h"
+#include "Exceptions.h"
+#include "../base/srvconfig.h"
+#include "../thrift/thrift_generated/DataReference_types.h"
+#include <Slog/Logger.h>
+#include <string>
+#include <stdexcept>
+#include <sstream>
+
+namespace meshsrvwrap
+{
+    using std::string;
+    using slog::Logger;
+    using std::runtime_error;
+    using std::ostringstream;
+
+    // =========================================================================
+    /// @brief Class for handling data references.
+    // =========================================================================
+    class DataReference
+    {
+        public:
+            template <class SrvType, class OptStruct>
+            static void getServer(const SrvType &input,
+                                  const OptStruct &opt,
+                                  string &host,
+                                  int &port);
+
+            template <class SrvType>
+            static void checkProtocol(const SrvType &input);
+
+            template<class SrvType, class OptStruct>
+            static void makeThriftReference(const SrvType &input,
+                                            const OptStruct &opt,
+                                            dataref::DataReference &output);
+
+            template<class SrvType>
+            static SrvType makeTCPDBReference(const SrvType &parent,
+                                              int ref);
+
+            template <class DBType, class SrvType, class OptStruct>
+            static DBType getTCPDB(const SrvType &input,
+                                   const OptStruct &opt);
+    
+            template <class SrvType, class OptStruct>
+            static long int hash(const SrvType &input,
+                                 const OptStruct &opt);
+
+            template <class SrvT1, class OptT1,
+                      class SrvT2, class OptT2>
+            static bool areEqual(SrvT1 &r1, OptT1 &opt1,
+                                 SrvT2 &r2, OptT2 &opt2);
+        private:
+            DataReference () {};
+            ~DataReference () {};
+    };
+    
+    // =========================================================================
+    /// @brief Conversion of service input to host/port.
+    /// 
+    /// @param input Input service instance.
+    /// @param opt Structure for handling optional parameters.
+    /// For thrift this->__is_set, for soap instance itself.
+    /// @param host Output host name.
+    /// @param port Output port.
+    // =========================================================================
+    template <class SrvType, class OptStruct>
+    void DataReference::getServer(const SrvType &input,
+                                  const OptStruct &opt,
+                                  string &host,
+                                  int &port)
+    {
+        Logger &logger = Logger::getLogger();
+        if (opt.server)
+        {
+            logger.getDebugSink()<<"custom server supplied "
+                <<input.server.host<<":"<<input.server.port;
+            host = input.server.host;
+            port = input.server.port;
+        }
+        else
+        {
+            host = DEFAULT_THRIFT_DBHOST;
+            port = DEFAULT_THRIFT_DBPORT;
+            logger.getDebugSink()<<"default server "
+                                   <<host<<":"<<port;
+
+        }
+    }
+     
+    // =========================================================================
+    /// @brief Throws an exception if protocol in the input is not supported.
+    // =========================================================================
+    template <class SrvType>
+    void DataReference::checkProtocol(const SrvType &input)
+    {
+        if (input.protocol != dataref::TCP_THRIFT_FRAMEDBINARY)
+        {
+            Logger::getLogger().getErrorSink()<<"desired data base protocol"
+                                              <<" is not supported. "
+                                              <<"Supported protocols are: "
+                                              <<" TCP_THRIFT_FRAMEDBINARY ";
+            throw ReferenceError("Requested reference protocol is not"
+                                " supported. Support: TCP_THRIFT_FRAMEDBINARY");
+        }
+    }
+
+    // =========================================================================
+    /// @brief Create an instance of a TCP Thrift client.
+    // =========================================================================
+    template <class DBType, class SrvType, class OptStruct>
+    DBType DataReference::getTCPDB(const SrvType &input,
+                                   const OptStruct &opt)
+    {
+        Logger &logger = Logger::getLogger();
+        logger.getInfoSink()<<"use tcp thrift framed binary";
+        string host;
+        int port;
+        DataReference::getServer(input, opt, host, port);
+        DBType client(host, port);
+        return client;
+    }
+
+    // =========================================================================
+    /// @brief Make a new reference.
+    /// 
+    /// @param parent A prototype that contains host and port specs.
+    /// @param ref Integer reference.
+    /// 
+    /// @return  New reference instance.
+    /// TBD Only thrift at the moment.
+    // =========================================================================
+    template<class SrvType>
+    SrvType DataReference::makeTCPDBReference(const SrvType &parent, int ref)
+    {
+        SrvType res;
+        res.protocol = dataref::TCP_THRIFT_FRAMEDBINARY;
+        res.__isset.protocol = true;
+        DataReference::getServer(parent, parent.__isset, res.server.host,
+                                 res.server.port);
+        ostringstream strm;
+        strm<<ref;
+        res.dataId = strm.str();
+        return res;
+    }
+
+    // =========================================================================
+    /// @brief Hash the reference.
+    // =========================================================================
+    template <class SrvType, class OptStruct>
+    long int DataReference::hash(const SrvType &input,
+                                 const OptStruct &opt)
+    {
+        string host;
+        int port;
+        DataReference::getServer(input, opt, host, port);
+        long int h = Basic::hash(input.protocol);
+        Basic::combineHash(h, Basic::hash(host));
+        Basic::combineHash(h, Basic::hash(port));
+        Basic::combineHash(h, Basic::hash(input.dataId));
+        return h;
+    }
+
+    // =========================================================================
+    /// @brief Copy input reference to output Thrift instance.
+    // =========================================================================
+    template<class SrvType, class OptStruct>
+    void DataReference::makeThriftReference(const SrvType &input,
+                                            const OptStruct &opt,
+                                            dataref::DataReference &output)
+    {
+        output.protocol = input.protocol;
+        output.dataId = input.dataId;
+        output.__isset.server = true;
+        DataReference::getServer(input, opt,
+                                 output.server.host, output.server.port);
+    }
+
+    // =========================================================================
+    /// @brief Check if two references are equal.
+    // =========================================================================
+    template <class SrvT1, class OptT1,
+              class SrvT2, class OptT2>
+    bool DataReference::areEqual(SrvT1 &r1, OptT1 &opt1,
+                                 SrvT2 &r2, OptT2 &opt2)
+    {
+        if (r1.protocol != r2.protocol)
+            return false;
+        if (r1.dataId.compare(r2.dataId) != 0)
+            return false;
+        string h1, h2;
+        int p1, p2;
+        getServer(r1, opt1, h1, p1);
+        getServer(r2, opt2, h2, p2);
+        if (h1.compare(h2) != 0)
+            return false;
+        if (p1 != p2)
+            return false;
+        return true;
+    }
+} //namespace meshsrvwrap
+
+
+#endif /* end of include guard: DATAREFERENCE_H_2QNJR3X8 */

service/conversion/Exceptions.h

+// Exceptions.h - Exceptions classes, part of MeshLib.
+// Copyright 2014 Sergey Bozhenkov, boz at ipp.mpg.de
+// Licensed under GPLv3 or later, see the COPYING file.
+#ifndef EXCEPTIONS_H_4GQK7UWN
+#define EXCEPTIONS_H_4GQK7UWN
+#include "../base/srvconfig.h"
+#ifdef HAVE_THRIFT
+#include "thrift_generated/MeshSrv_types.h"
+#endif
+#include <exception>
+#include <string>
+
+namespace meshsrvwrap
+{
+    using std::exception;
+    using std::string;
+
+    // =========================================================================
+    /// @brief Failure in accessing the reference.
+    // =========================================================================
+    class ReferenceError : public
+#ifdef HAVE_THRIFT
+                                   dataref::ReferenceError
+#else
+
+                                   exception
+#endif
+    {
+        public:
+            ReferenceError (const string &msg) {message = msg;};
+            ~ReferenceError() throw() {};
+            const char* what() const throw() {return message.c_str();};
+#ifndef HAVE_THRIFT
+            string message;
+#endif
+    };
+    //
+    // =========================================================================
+    /// @brief Error in the model
+    // =========================================================================
+    class ModelError : public
+#ifdef HAVE_THRIFT
+                                   meshsrv::ModelError
+#else
+
+                                   exception
+#endif
+    {
+        public:
+            ModelError (const string &msg) {message = msg;};
+            ~ModelError() throw() {};
+            const char* what() const throw() {return message.c_str();};
+#ifndef HAVE_THRIFT
+            string message;
+#endif
+    };
+    
+    // =========================================================================
+    /// @brief Unequal dimensions.
+    // =========================================================================
+    class DimensionsError : public
+#ifdef HAVE_THRIFT
+                                   geometry::DimensionsError
+#else
+