diff --git a/.gitignore b/.gitignore
index d87980fd00fb59300f8fbdc27a055e9854a4d6d6..42b843b17df6e0e0576fe16e2a24ee9f807a1086 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,3 +1,4 @@
 build/
 .vscode/
 MSVC2017/
+VS2017/
diff --git a/src/GridGenerator/geometries/TriangularMesh/TriangularMeshStrategy.cpp b/src/GridGenerator/geometries/TriangularMesh/TriangularMeshStrategy.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..e5936122e8f29ccc643f3655672806ef1887eb1e
--- /dev/null
+++ b/src/GridGenerator/geometries/TriangularMesh/TriangularMeshStrategy.cpp
@@ -0,0 +1,256 @@
+#include "TriangularMeshStrategy.h"
+
+#include "../Triangle/Triangle.h"
+#include "TriangularMesh.h"
+#include "grid/GridImp.h"
+
+#include "numerics/geometry3d/GbTriFaceMesh3D.h"
+#include "grid/NodeValues.h"
+
+void TriangularMeshDiscretizationStrategy::removeOddBoundaryCellNodes(GridImp* grid)
+{
+#pragma omp parallel for
+    for (uint index = 0; index < grid->getSize(); index++)
+        grid->removeOddBoundaryCellNode(index);
+}
+
+
+void PointInObjectDiscretizationStrategy::doDiscretize(TriangularMesh* triangularMesh, GridImp* grid, char InnerType, char OuterType)
+{
+    auto mesh = triangularMesh->getGbTriFaceMesh3D();
+
+    for (uint i = 0; i < grid->getSize(); i++)
+    {
+        real x, y, z;
+        grid->transIndexToCoords(i, x, y, z);
+
+        if (mesh->isPointInGbObject3D(x, y, z))
+            grid->setNodeTo(i, InnerType);
+        //else
+        //    grid->setNodeTo(i, OuterType);
+    }
+
+    delete mesh;
+}
+
+
+void RayCastingDiscretizationStrategy::doDiscretize(TriangularMesh* triangularMesh, GridImp* grid, char InnerType, char OuterType)
+{
+    //    auto mesh = triangularMesh->getGbTriFaceMesh3D();
+
+    //    const real minXExact = triangularMesh->minmax.minX;
+    //    const real minYExact = triangularMesh->minmax.minY;
+    //    const real minZExact = triangularMesh->minmax.minZ;
+
+    //    const real maxXExact = triangularMesh->minmax.maxX;
+    //    const real maxYExact = triangularMesh->minmax.maxY;
+    //    const real maxZExact = triangularMesh->minmax.maxZ;
+
+    //    const auto min = grid->getMinimumOnNode(Vertex(minXExact, minYExact, minZExact));
+
+    //    const real minX = min.x;
+    //    const real minY = min.y;
+    //    const real minZ = min.z;
+
+    //    const auto max = grid->getMaximumOnNode(Vertex(maxXExact, maxYExact, maxZExact));
+
+    //    const real maxX = max.x;
+    //    const real maxY = max.y;
+    //    const real maxZ = max.z;
+
+
+    //    real x, y, z;
+    //    for (z = minZ; z <= maxZ; z += grid->getDelta())
+    //    {
+    //        for (y = minY; y <= maxY; y += grid->getDelta())
+    //        {
+    //            for (x = minX; x <= maxX; x += grid->getDelta())
+    //            {
+    //                grid->setNodeTo(grid->transCoordToIndex(x, y, z), InnerType);
+    //            }
+    //        }
+    //    }
+
+
+
+    //    int counter = 0;
+
+    //    // Test line intersection
+    //    for (z = minZ; z <= maxZ; z += grid->getDelta())
+    //    {
+    //        for (y = minY; y <= maxY; y += grid->getDelta())
+    //        {
+    //            for (x = minX; x <= maxX; x += grid->getDelta())
+    //            {
+    //                counter++;
+    //                if (mesh->intersectLine((x - grid->getDelta()), y, z, x, y, z)) 
+    //                    break;
+    //                grid->setNodeTo(grid->transCoordToIndex(x, y, z), OuterType);
+    //            }
+    //        }
+    //    }
+
+    //    // Test line intersection from opposite direction
+    //    for (z = minZ; z <= maxZ; z += grid->getDelta())
+    //    {
+    //        for (y = minY; y <= maxY; y += grid->getDelta())
+    //        {
+    //            for (x = maxX; x >= minX; x -= grid->getDelta())
+    //            {
+    //                if (!grid->isNode(grid->transCoordToIndex(x, y, z), OuterType))
+    //                {
+    //                    counter++;
+    //                    if (mesh->intersectLine((x + grid->getDelta()), y, z, x, y, z))
+    //                        break;
+    //                    grid->setNodeTo(grid->transCoordToIndex(x, y, z), OuterType);
+    //                }
+    //            }
+    //        }
+    //    }
+
+    //    // Test line intersection
+    //    for (z = minZ; z <= maxZ; z += grid->getDelta())
+    //    {
+    //        for (x = minX; x <= maxX; x += grid->getDelta())
+    //        {
+    //            for (y = minY; y <= maxY; y += grid->getDelta())
+    //            {
+    //                if (!grid->isNode(grid->transCoordToIndex(x, y, z), OuterType))
+    //                {
+    //                    counter++;
+    //                    if (mesh->intersectLine(x, (y - grid->getDelta()), z, x, y, z)) 
+    //                        break;
+    //                    grid->setNodeTo(grid->transCoordToIndex(x, y, z), OuterType);
+    //                }
+    //            }
+    //        }
+    //    }
+
+    //    // Test line intersection from opposite direction
+    //    for (z = minZ; z <= maxZ; z += grid->getDelta())
+    //    {
+    //        for (x = minX; x <= maxX; x += grid->getDelta())
+    //        {
+    //            for (y = maxY; y >= minY; y -= grid->getDelta())
+    //            {
+    //                if (!grid->isNode(grid->transCoordToIndex(x, y, z), OuterType))
+    //                {
+    //                    counter++;
+    //                    if (mesh->intersectLine(x, (y + grid->getDelta()), z, x, y, z))
+    //                        break;
+    //                    grid->setNodeTo(grid->transCoordToIndex(x, y, z), OuterType);
+    //                }
+    //            }
+    //        }
+    //    }
+
+    //    // Test line intersection
+    //    for (x = minX; x <= maxX; x += grid->getDelta())
+    //    {
+    //        for (y = minY; y <= maxY; y += grid->getDelta())
+    //        {
+    //            for (z = minZ; z <= maxZ; z += grid->getDelta())
+    //            {
+    //                if (!grid->isNode(grid->transCoordToIndex(x, y, z), OuterType))
+    //                {
+    //                    counter++;
+    //                    if (mesh->intersectLine(x, y, (z - grid->getDelta()), x, y, z)) 
+    //                        break;
+    //                    grid->setNodeTo(grid->transCoordToIndex(x, y, z), OuterType);
+    //                }
+    //            }
+    //        }
+    //    }
+
+    //    // Test line intersection from opposite direction
+    //    for (x = minX; x <= maxX; x += grid->getDelta())
+    //    {
+    //        for (y = minY; y <= maxY; y += grid->getDelta())
+    //        {
+    //            for (z = maxZ; z >= minZ; z -= grid->getDelta())
+    //            {
+    //                if (!grid->isNode(grid->transCoordToIndex(x, y, z), OuterType))
+    //                {
+    //                    counter++;
+    //                    if (mesh->intersectLine(x, y, (z + grid->getDelta()), x, y, z)) 
+    //                        break;
+    //                    grid->setNodeTo(grid->transCoordToIndex(x, y, z), OuterType);
+    //                }
+    //            }
+    //        }
+    //    }
+
+    //    delete mesh;
+}
+
+
+
+void PointUnderTriangleStrategy::doDiscretize(TriangularMesh* triangularMesh, GridImp* grid, char innerType, char outerType)
+{
+#pragma omp parallel for
+    for (long i = 0; i < triangularMesh->size; i++)
+        this->meshReverse(triangularMesh->triangles[i], grid, innerType);
+
+    this->findInsideNodes(grid, innerType);
+
+#pragma omp parallel for
+    for (uint i = 0; i < grid->getSize(); i++)
+        this->setNegativeDirBorderTo(grid, i, innerType);
+}
+
+void PointUnderTriangleStrategy::meshReverse(Triangle& triangle, GridImp* grid, char innerType)
+{
+    auto box = grid->getBoundingBoxOnNodes(triangle);
+
+    const real delta = grid->getDelta();
+    triangle.initalLayerThickness(delta);
+
+    for (real x = box.minX; x <= box.maxX; x += delta)
+    {
+        for (real y = box.minY; y <= box.maxY; y += delta)
+        {
+            for (real z = box.minZ; z <= box.maxZ; z += delta)
+            {
+                const uint index = grid->transCoordToIndex(x, y, z);
+
+                const Vertex point(x, y, z);
+
+                const char pointValue = triangle.isUnderFace(point);
+
+                if (pointValue == NEGATIVE_DIRECTION_BORDER)
+                    grid->setNodeTo(index, NEGATIVE_DIRECTION_BORDER);
+                else if (pointValue == INSIDE)
+                    grid->setNodeTo(index, innerType);
+            }
+        }
+    }
+}
+
+HOSTDEVICE void PointUnderTriangleStrategy::findInsideNodes(GridImp* grid, char innerType)
+{
+    bool foundInsideNode = true;
+    while (foundInsideNode)
+    {
+        foundInsideNode = false;
+        for (uint index = 0; index < grid->getSize(); index++)
+            this->setInsideNode(grid, index, foundInsideNode, innerType);
+    }
+}
+
+HOSTDEVICE void PointUnderTriangleStrategy::setInsideNode(GridImp* grid, const uint &index, bool &insideNodeFound, char innerType)
+{
+    if (grid->isNode(index, NEGATIVE_DIRECTION_BORDER))
+        return;
+
+    if (!grid->isNode(index, innerType) && grid->nodeInNextCellIs(index, innerType))
+    {
+        grid->setNodeTo(index, innerType);
+        insideNodeFound = true;
+    }
+}
+
+HOSTDEVICE void PointUnderTriangleStrategy::setNegativeDirBorderTo(GridImp* grid, const uint &index, char innerType)
+{
+    if (grid->isNode(index, NEGATIVE_DIRECTION_BORDER))
+        grid->setNodeTo(index, innerType);
+}
\ No newline at end of file
diff --git a/src/GridGenerator/geometries/TriangularMesh/TriangularMeshStrategy.h b/src/GridGenerator/geometries/TriangularMesh/TriangularMeshStrategy.h
index 80dc7fa02cf40024486a6a5f3b065aad48c40e16..f4e70be94053b516730c00ed2018e91e6217edb7 100644
--- a/src/GridGenerator/geometries/TriangularMesh/TriangularMeshStrategy.h
+++ b/src/GridGenerator/geometries/TriangularMesh/TriangularMeshStrategy.h
@@ -3,15 +3,13 @@
 
 #include "GridGenerator/global.h"
 
-#include "../Triangle/Triangle.h"
-#include "TriangularMesh.h"
-#include "numerics/geometry3d/GbTriFaceMesh3D.h"
-#include "grid/GridImp.h"
-#include "utilities/logger/Logger.h"
-#include "grid/NodeValues.h"
+#include "VirtualFluidsDefinitions.h"
 
+class GridImp;
+class TriangularMesh;
+struct Triangle;
 
-class TriangularMeshDiscretizationStrategy
+class VF_PUBLIC TriangularMeshDiscretizationStrategy
 {
 public:
     TriangularMeshDiscretizationStrategy() {}
@@ -26,274 +24,44 @@ public:
 
 private:
     virtual void doDiscretize(TriangularMesh* triangularMesh, GridImp* grid, char InnerType, char OuterType) = 0;
-    void removeOddBoundaryCellNodes(GridImp* grid)
-    {
-#pragma omp parallel for
-        for (uint index = 0; index < grid->getSize(); index++)
-            grid->removeOddBoundaryCellNode(index);
-    }
-
-
+    void removeOddBoundaryCellNodes(GridImp* grid);
 };
 
 
 
-class PointInObjectDiscretizationStrategy : public TriangularMeshDiscretizationStrategy
+class VF_PUBLIC PointInObjectDiscretizationStrategy : public TriangularMeshDiscretizationStrategy
 {
 public:
     PointInObjectDiscretizationStrategy() {}
     virtual ~PointInObjectDiscretizationStrategy() {}
 
-    virtual void doDiscretize(TriangularMesh* triangularMesh, GridImp* grid, char InnerType, char OuterType)
-    {
-        auto mesh = triangularMesh->getGbTriFaceMesh3D();
-
-        for (uint i = 0; i < grid->getSize(); i++)
-        {
-            real x, y, z;
-            grid->transIndexToCoords(i, x, y, z);
-
-            if (mesh->isPointInGbObject3D(x, y, z))
-                grid->setNodeTo(i, InnerType);
-            //else
-            //    grid->setNodeTo(i, OuterType);
-        }
-
-        delete mesh;
-    }
+    virtual void doDiscretize(TriangularMesh* triangularMesh, GridImp* grid, char InnerType, char OuterType);
 };
 
-class RayCastingDiscretizationStrategy : public TriangularMeshDiscretizationStrategy
+class VF_PUBLIC RayCastingDiscretizationStrategy : public TriangularMeshDiscretizationStrategy
 {
 public:
     RayCastingDiscretizationStrategy() {}
     virtual ~RayCastingDiscretizationStrategy() {}
 
-    virtual void doDiscretize(TriangularMesh* triangularMesh, GridImp* grid, char InnerType, char OuterType)
-    {
-        auto mesh = triangularMesh->getGbTriFaceMesh3D();
-
-        const real minXExact = triangularMesh->minmax.minX;
-        const real minYExact = triangularMesh->minmax.minY;
-        const real minZExact = triangularMesh->minmax.minZ;
-
-        const real maxXExact = triangularMesh->minmax.maxX;
-        const real maxYExact = triangularMesh->minmax.maxY;
-        const real maxZExact = triangularMesh->minmax.maxZ;
-
-        const auto min = grid->getMinimumOnNode(Vertex(minXExact, minYExact, minZExact));
-
-        const real minX = min.x;
-        const real minY = min.y;
-        const real minZ = min.z;
-
-        const auto max = grid->getMaximumOnNode(Vertex(maxXExact, maxYExact, maxZExact));
-
-        const real maxX = max.x;
-        const real maxY = max.y;
-        const real maxZ = max.z;
-
-
-        real x, y, z;
-        for (z = minZ; z <= maxZ; z += grid->getDelta())
-        {
-            for (y = minY; y <= maxY; y += grid->getDelta())
-            {
-                for (x = minX; x <= maxX; x += grid->getDelta())
-                {
-                    grid->setNodeTo(grid->transCoordToIndex(x, y, z), InnerType);
-                }
-            }
-        }
-
-
-
-        int counter = 0;
-
-        // Test line intersection
-        for (z = minZ; z <= maxZ; z += grid->getDelta())
-        {
-            for (y = minY; y <= maxY; y += grid->getDelta())
-            {
-                for (x = minX; x <= maxX; x += grid->getDelta())
-                {
-                    counter++;
-                    if (mesh->intersectLine((x - grid->getDelta()), y, z, x, y, z)) 
-                        break;
-                    grid->setNodeTo(grid->transCoordToIndex(x, y, z), OuterType);
-                }
-            }
-        }
-
-        // Test line intersection from opposite direction
-        for (z = minZ; z <= maxZ; z += grid->getDelta())
-        {
-            for (y = minY; y <= maxY; y += grid->getDelta())
-            {
-                for (x = maxX; x >= minX; x -= grid->getDelta())
-                {
-                    if (!grid->isNode(grid->transCoordToIndex(x, y, z), OuterType))
-                    {
-                        counter++;
-                        if (mesh->intersectLine((x + grid->getDelta()), y, z, x, y, z))
-                            break;
-                        grid->setNodeTo(grid->transCoordToIndex(x, y, z), OuterType);
-                    }
-                }
-            }
-        }
-
-        // Test line intersection
-        for (z = minZ; z <= maxZ; z += grid->getDelta())
-        {
-            for (x = minX; x <= maxX; x += grid->getDelta())
-            {
-                for (y = minY; y <= maxY; y += grid->getDelta())
-                {
-                    if (!grid->isNode(grid->transCoordToIndex(x, y, z), OuterType))
-                    {
-                        counter++;
-                        if (mesh->intersectLine(x, (y - grid->getDelta()), z, x, y, z)) 
-                            break;
-                        grid->setNodeTo(grid->transCoordToIndex(x, y, z), OuterType);
-                    }
-                }
-            }
-        }
-
-        // Test line intersection from opposite direction
-        for (z = minZ; z <= maxZ; z += grid->getDelta())
-        {
-            for (x = minX; x <= maxX; x += grid->getDelta())
-            {
-                for (y = maxY; y >= minY; y -= grid->getDelta())
-                {
-                    if (!grid->isNode(grid->transCoordToIndex(x, y, z), OuterType))
-                    {
-                        counter++;
-                        if (mesh->intersectLine(x, (y + grid->getDelta()), z, x, y, z))
-                            break;
-                        grid->setNodeTo(grid->transCoordToIndex(x, y, z), OuterType);
-                    }
-                }
-            }
-        }
-
-        // Test line intersection
-        for (x = minX; x <= maxX; x += grid->getDelta())
-        {
-            for (y = minY; y <= maxY; y += grid->getDelta())
-            {
-                for (z = minZ; z <= maxZ; z += grid->getDelta())
-                {
-                    if (!grid->isNode(grid->transCoordToIndex(x, y, z), OuterType))
-                    {
-                        counter++;
-                        if (mesh->intersectLine(x, y, (z - grid->getDelta()), x, y, z)) 
-                            break;
-                        grid->setNodeTo(grid->transCoordToIndex(x, y, z), OuterType);
-                    }
-                }
-            }
-        }
-
-        // Test line intersection from opposite direction
-        for (x = minX; x <= maxX; x += grid->getDelta())
-        {
-            for (y = minY; y <= maxY; y += grid->getDelta())
-            {
-                for (z = maxZ; z >= minZ; z -= grid->getDelta())
-                {
-                    if (!grid->isNode(grid->transCoordToIndex(x, y, z), OuterType))
-                    {
-                        counter++;
-                        if (mesh->intersectLine(x, y, (z + grid->getDelta()), x, y, z)) 
-                            break;
-                        grid->setNodeTo(grid->transCoordToIndex(x, y, z), OuterType);
-                    }
-                }
-            }
-        }
-
-        delete mesh;
-    }
+    virtual void RayCastingDiscretizationStrategy::doDiscretize(TriangularMesh* triangularMesh, GridImp* grid, char InnerType, char OuterType);
 };
 
-class PointUnderTriangleStrategy : public TriangularMeshDiscretizationStrategy
+class VF_PUBLIC PointUnderTriangleStrategy : public TriangularMeshDiscretizationStrategy
 {
 public:
     PointUnderTriangleStrategy() {}
     virtual ~PointUnderTriangleStrategy() {}
-    void doDiscretize(TriangularMesh* triangularMesh, GridImp* grid, char innerType, char outerType) override
-    {
-#pragma omp parallel for
-        for (long i = 0; i < triangularMesh->size; i++)
-            this->meshReverse(triangularMesh->triangles[i], grid, innerType);
-
-        this->findInsideNodes(grid, innerType);
-
-#pragma omp parallel for
-        for (uint i = 0; i < grid->getSize(); i++)
-            this->setNegativeDirBorderTo(grid, i, innerType);
-    }
+    void doDiscretize(TriangularMesh* triangularMesh, GridImp* grid, char innerType, char outerType) override;
 
 private:
-    HOSTDEVICE void meshReverse(Triangle &triangle, GridImp* grid, char innerType)
-    {
-        auto box = grid->getBoundingBoxOnNodes(triangle);
-
-        const real delta = grid->getDelta();
-        triangle.initalLayerThickness(delta);
+    HOSTDEVICE void meshReverse(Triangle& triangle, GridImp* grid, char innerType);
 
-        for (real x = box.minX; x <= box.maxX; x += delta)
-        {
-            for (real y = box.minY; y <= box.maxY; y += delta)
-            {
-                for (real z = box.minZ; z <= box.maxZ; z += delta)
-                {
-                    const uint index = grid->transCoordToIndex(x, y, z);
+    HOSTDEVICE void findInsideNodes(GridImp* grid, char innerType);
 
-                    const Vertex point(x, y, z);
+    HOSTDEVICE void setInsideNode(GridImp* grid, const uint &index, bool &insideNodeFound, char innerType);
 
-                    const char pointValue = triangle.isUnderFace(point);
-
-                    if (pointValue == NEGATIVE_DIRECTION_BORDER)
-                        grid->setNodeTo(index, NEGATIVE_DIRECTION_BORDER);
-                    else if (pointValue == INSIDE)
-                        grid->setNodeTo(index, innerType);
-                }
-            }
-        }
-    }
-
-    HOSTDEVICE void findInsideNodes(GridImp* grid, char innerType)
-    {
-        bool foundInsideNode = true;
-        while (foundInsideNode)
-        {
-            foundInsideNode = false;
-            for (uint index = 0; index < grid->getSize(); index++)
-                this->setInsideNode(grid, index, foundInsideNode, innerType);
-        }
-    }
-
-    HOSTDEVICE void setInsideNode(GridImp* grid, const uint &index, bool &insideNodeFound, char innerType)
-    {
-        if (grid->isNode(index, NEGATIVE_DIRECTION_BORDER))
-            return;
-
-        if (!grid->isNode(index, innerType) && grid->nodeInNextCellIs(index, innerType))
-        {
-            grid->setNodeTo(index, innerType);
-            insideNodeFound = true;
-        }
-    }
-
-    HOSTDEVICE void setNegativeDirBorderTo(GridImp* grid, const uint &index, char innerType)
-    {
-        if (grid->isNode(index, NEGATIVE_DIRECTION_BORDER))
-            grid->setNodeTo(index, innerType);
-    }
+    HOSTDEVICE void setNegativeDirBorderTo(GridImp* grid, const uint &index, char innerType);
 
 };
 
diff --git a/src/GridGenerator/grid/GridBuilder/MultipleGridBuilder.cpp b/src/GridGenerator/grid/GridBuilder/MultipleGridBuilder.cpp
index 8cf446aac8246c524f0327f3d00dc29758ca26f0..04a351dcacce7e5057fa0590ab00dd00e94f038c 100644
--- a/src/GridGenerator/grid/GridBuilder/MultipleGridBuilder.cpp
+++ b/src/GridGenerator/grid/GridBuilder/MultipleGridBuilder.cpp
@@ -1,4 +1,7 @@
 #include "MultipleGridBuilder.h"
+
+#include <sstream>
+
 #include "utilities/math/Math.h"
 #include "../Grid.h"
 #include "../GridFactory.h"
diff --git a/src/GridGenerator/grid/GridStrategy/GridCpuStrategy/GridCpuStrategy.cpp b/src/GridGenerator/grid/GridStrategy/GridCpuStrategy/GridCpuStrategy.cpp
index 5f324e92922ea5d4ee9a0f377149e11e29c048d8..8d55383fa68d5ca31ba74e245608f7d3ab3d762a 100644
--- a/src/GridGenerator/grid/GridStrategy/GridCpuStrategy/GridCpuStrategy.cpp
+++ b/src/GridGenerator/grid/GridStrategy/GridCpuStrategy/GridCpuStrategy.cpp
@@ -15,8 +15,6 @@
 #include "grid/NodeValues.h"
 
 #include "grid/GridInterface.h"
-#include "io/GridVTKWriter/GridVTKWriter.h"
-#include "numerics/geometry3d/GbTriFaceMesh3D.h"
 
 void GridCpuStrategy::allocateGridMemory(SPtr<GridImp> grid)
 {
diff --git a/src/VirtualFluidsBasics/numerics/geometry3d/GbTriFaceMesh3D.cpp b/src/VirtualFluidsBasics/numerics/geometry3d/GbTriFaceMesh3D.cpp
index 10f3c07f4ff6669f35be0ec6df39fd3cf8f2bfab..0beb2b12b55b91372281f4a0cd1a8832752a337c 100644
--- a/src/VirtualFluidsBasics/numerics/geometry3d/GbTriFaceMesh3D.cpp
+++ b/src/VirtualFluidsBasics/numerics/geometry3d/GbTriFaceMesh3D.cpp
@@ -1,3 +1,4 @@
+
 #include <numerics/geometry3d/GbTriFaceMesh3D.h>
 
 #include <numerics/geometry3d/GbCuboid3D.h>
@@ -14,31 +15,39 @@
 #include <numerics/geometry3d/KdTree/intersectionhandler/KdCountLineIntersectionHandler.h>
 #include <numerics/geometry3d/KdTree/intersectionhandler/KdCountRayIntersectionHandler.h>
 
+#define MAX_ITER 10
+
 using namespace std;
 
 GbTriFaceMesh3D::GbTriFaceMesh3D() 
    :   GbObject3D()
      , buildVertTriRelationMap(false)
      , kdTree(NULL)
-     , kdTreeValid(false)
+     , transX1(0.0)
+     , transX2(0.0)
+     , transX3(0.0)
+     , transferViaFilename(false)
+
 {
    this->setName("CAB_GbTriFaceMesh3D");
    this->nodes          = new vector<Vertex>;
    this->triangles      = new vector<TriFace>;
    this->consistent     = false;
-   //this->kdtreeSplitAlg = KDTREE_SHAPLIT;
-   this->kdtreeSplitAlg = KDTREE_SPATIALSPLIT;
+   this->kdtreeSplitAlg = KDTREE_SAHPLIT;
 }
 /*=======================================================================*/
-GbTriFaceMesh3D::GbTriFaceMesh3D(  string name, vector<Vertex>* nodes, vector<TriFace>* triangles, KDTREE_SPLITAGORITHM splitAlg, bool removeRedundantNodes)
+GbTriFaceMesh3D::GbTriFaceMesh3D(string name, vector<Vertex>* nodes, vector<TriFace>* triangles, KDTREE_SPLITAGORITHM splitAlg, bool removeRedundantNodes)
    :  GbObject3D()
     , nodes(nodes)
     , triangles(triangles)
     , buildVertTriRelationMap(false)
     , consistent(false)
     , kdTree(NULL)
-    , kdTreeValid(false)
     , kdtreeSplitAlg(splitAlg)
+    , transX1(0.0)
+    , transX2(0.0)
+    , transX3(0.0)
+    , transferViaFilename(false)
 {
    if( name.empty() ) throw UbException(UB_EXARGS,"no name specified");
    if( !nodes       ) throw UbException(UB_EXARGS,"no nodes specified");
@@ -58,7 +67,6 @@ GbTriFaceMesh3D::GbTriFaceMesh3D(  string name, vector<Vertex>* nodes, vector<Tr
 /*=======================================================================*/
 GbTriFaceMesh3D::~GbTriFaceMesh3D()
 {
-   UBLOG(logERROR,"~GbTriFaceMesh3D")
    if( nodes     ) { delete nodes;     nodes     = NULL; }
    if( triangles ) { delete triangles; triangles = NULL; }
    if( kdTree    ) { delete kdTree;    kdTree    = NULL; }
@@ -83,16 +91,52 @@ void GbTriFaceMesh3D::init()
    x3max      = 0.0;
    x3center   = 0.0;
    consistent = false;
-   kdTreeValid = false;
 }
+/*======================================================================*/
+GbTriFaceMesh3D* GbTriFaceMesh3D::clone()
+{
+   vector<GbTriFaceMesh3D::Vertex>    *newNodes     = new vector<GbTriFaceMesh3D::Vertex>;
+   vector<GbTriFaceMesh3D::TriFace>   *newTriangles = new vector<GbTriFaceMesh3D::TriFace>;
+
+   int numberNodes = (int)this->nodes->size();
+
+   double x,y,z;
+   for(int u=0;u<numberNodes;u++)
+   {
+      x=(*nodes)[u].x;
+      y=(*nodes)[u].y;
+      z=(*nodes)[u].z;
+      newNodes->push_back(GbTriFaceMesh3D::Vertex((float)x,(float)y,(float)z));
+   }
+   int numberTris  = (int)this->triangles->size();
+   UBLOG(logDEBUG1,"numberTris:"<<numberTris);
+
+   int id1,id2,id3;
+   for(int u=0;u<numberTris;u++)
+   {
+      id1 = (*this->triangles)[u].v1;
+      id2 = (*this->triangles)[u].v2;
+      id3 = (*this->triangles)[u].v3;
+      newTriangles->push_back(GbTriFaceMesh3D::TriFace(id1,id2,id3));
+      //cout<<u<<" - id1,id2,id3:"<<id1<<","<<id2<<","<<id3<<endl;
+   }
+   UBLOG(logDEBUG1,"Tris gelesen");
+
+   GbTriFaceMesh3D* mesh = new GbTriFaceMesh3D("no name", newNodes, newTriangles);
+   UBLOG(logDEBUG1,"mesh cloned ...");
+
+   return mesh;
+}
+
 /*======================================================================*/
 //checks for doppelt nodes und fixed Dreicke die zweimal denselben Knoten haben
 void GbTriFaceMesh3D::deleteRedundantNodes()
 {
-    UBLOG(logINFO,"GbTriFaceMesh3D::deleteRedundantNodes - Nodes before deleting redundant: "<<this->nodes->size());
+    UBLOG(logDEBUG1,"GbTriFaceMesh3D::deleteRedundantNodes - Nodes before deleting redundant: "<<this->nodes->size());
 
     map<Vertex,size_t/*new vecIndex*/> vertexMap;
     map<Vertex,size_t/*new vecIndex*/>::iterator pos;
+    map<Vertex,size_t/*new vecIndex*/>::iterator it;
     
     vector<TriFace>& tris     = *this->triangles;
     vector<Vertex>&  oldNodes = *this->nodes;
@@ -100,12 +144,25 @@ void GbTriFaceMesh3D::deleteRedundantNodes()
 
     for(size_t t=0; t<tris.size(); t++)
     {
+       if(t%100==0) UBLOG(logDEBUG5,"GbTriFaceMesh3D::deleteRedundantNodes - tri: "<<(t)<<" von "<<tris.size());
        TriFace& tri = tris[t];
        //Knoten bereits in neuem node vector?
        for(int v=0; v<=2; v++)
        {
           Vertex& vert = tri.getNode(v,oldNodes);
-          pos=vertexMap.find( vert );
+          //pos=vertexMap.find( vert );
+          //if( pos==vertexMap.end() )
+          {
+             for(pos=vertexMap.begin();pos!=vertexMap.end();pos++)
+             {
+               Vertex rhs = pos->first;
+             //if(UbMath::inClosedInterval(vert.z,0.01999, 0.02001))
+               if ( fabs(vert.x-rhs.x)<1.E-5 && fabs(vert.y-rhs.y)<1.E-5 && fabs(vert.z-rhs.z)<1.E-5 )
+               {
+                  break;
+               }
+             }
+          }
           if( pos!=vertexMap.end() ) tri.setNode(v, (int)pos->second);
           else
           {
@@ -119,8 +176,56 @@ void GbTriFaceMesh3D::deleteRedundantNodes()
 
     std::swap(*nodes,newNodes);
 
-    UBLOG(logINFO,"GbTriFaceMesh3D::deleteRedundantNodes - Nodes after deleting redundant:"<<this->nodes->size());
-    UBLOG(logINFO,"GbTriFaceMesh3D::deleteRedundantNodes - checking for triangles that have same node several times or are lines!!!");
+    UBLOG(logDEBUG1,"GbTriFaceMesh3D::deleteRedundantNodes - Nodes after deleting redundant:"<<this->nodes->size());
+    //
+    //Das geht irgendwie nicht ...
+    //
+    //UBLOG(logDEBUG1,"GbTriFaceMesh3D::deleteRedundantNodes - checking for double triangles !!!");
+    //UBLOG(logDEBUG1,"GbTriFaceMesh3D::deleteRedundantNodes - Triangles before deleting redundant: "<<this->triangles->size());
+    //vector<TriFace> newSingleTris;
+    //newSingleTris.reserve( this->triangles->size() );
+    //for(size_t t=0; t<tris.size(); t++)
+    //{
+    //   Vertex& v1 = tris[t].getNode(0,*nodes); 
+    //   Vertex& v2 = tris[t].getNode(1,*nodes); 
+    //   Vertex& v3 = tris[t].getNode(2,*nodes); 
+
+    //   if(UbMath::greater(std::fabs(v1.x), 0.0634) && UbMath::inClosedInterval(v1.z, 0.01999, 0.02001))
+    //   {
+    //      UBLOG2(logINFO,std::cout, "V1:"<<v1.x<<" "<<v1.y<<" "<<v1.z);
+    //   }
+    //   if(UbMath::greater(std::fabs(v2.x), 0.0634) && UbMath::inClosedInterval(v2.z, 0.01999, 0.02001))
+    //   {
+    //      UBLOG2(logINFO,std::cout, "V2:"<<v2.x<<" "<<v2.y<<" "<<v2.z);
+    //   }
+    //   if(UbMath::greater(std::fabs(v3.x), 0.0634) && UbMath::inClosedInterval(v3.z, 0.01999, 0.02001))
+    //   {
+    //      UBLOG2(logINFO,std::cout, "V3:"<<v3.x<<" "<<v3.y<<" "<<v3.z);
+    //   }
+
+    //   bool inList = false;
+    //   for(size_t u=0; u<newSingleTris.size(); u++)
+    //   {
+    //      Vertex& vn1 = newSingleTris[t].getNode(0,*nodes); 
+    //      Vertex& vn2 = newSingleTris[t].getNode(1,*nodes); 
+    //      Vertex& vn3 = newSingleTris[t].getNode(2,*nodes); 
+
+    //      if(v1==vn1 && v2==vn2 && v3==vn3)      inList = true;
+    //      else if(v1==vn1 && v2==vn3 && v3==vn2) inList = true;
+    //      else if(v1==vn2 && v2==vn3 && v3==vn1) inList = true;
+    //      else if(v1==vn2 && v2==vn1 && v3==vn3) inList = true;
+    //      else if(v1==vn3 && v2==vn1 && v3==vn2) inList = true;
+    //      else if(v1==vn3 && v2==vn2 && v3==vn1) inList = true;
+    //   }
+    //   if(!inList) newSingleTris.push_back(tris[t]);
+    //   else 
+    //      UBLOG(logDEBUG1,"GbTriFaceMesh3D::deleteRedundantNodes - inList !!!!");
+    
+    //}
+    //swap(tris,newSingleTris);
+
+    //UBLOG(logDEBUG1,"GbTriFaceMesh3D::deleteRedundantNodes - Triangles after deleting redundant:"<<this->triangles->size());
+    UBLOG(logDEBUG1,"GbTriFaceMesh3D::deleteRedundantNodes - checking for triangles that have same node several times or are lines!!!");
     int counter1 = 0;
     int counter2 = 0;
     vector<TriFace> newTris;
@@ -142,23 +247,23 @@ void GbTriFaceMesh3D::deleteRedundantNodes()
     }
     if(counter1)
     {
-       UBLOG(logWARNING,"GbTriFaceMesh3D::deleteRedundantNodes - ### Warning ###: found and removed  "<<counter1<<" triangle with double nodes!");
+       UBLOG(logDEBUG1,"GbTriFaceMesh3D::deleteRedundantNodes - ### Warning ###: found and removed  "<<counter1<<" triangle with double nodes!");
     }
     if(counter2)
     {
-       UBLOG(logWARNING,"GbTriFaceMesh3D::deleteRedundantNodes - ### Warning ###: found and removed  "<<counter2<<" triangle that are lines!") ;
+       UBLOG(logDEBUG1,"GbTriFaceMesh3D::deleteRedundantNodes - ### Warning ###: found and removed  "<<counter2<<" triangle that are lines!") ;
     }
-    if(!counter1 && !counter2) { UBLOG(logINFO,"GbTriFaceMesh3D::deleteRedundantNodes - alles gut... nix doppelt"); }
+    if(!counter1 && !counter2) { UBLOG(logDEBUG1,"GbTriFaceMesh3D::deleteRedundantNodes - alles gut... nix doppelt"); }
     else swap(tris,newTris);
     
-    UBLOG(logINFO,"GbTriFaceMesh3D::deleteRedundantNodes - done" );
+    UBLOG(logDEBUG1,"GbTriFaceMesh3D::deleteRedundantNodes - done" );
     this->calculateValues();
-
-    UBLOG(logINFO,"GbTriFaceMesh3D::deleteRedundantNodes !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
-    UBLOG(logINFO,"GbTriFaceMesh3D::deleteRedundantNodes !!! Falls das FeTriFaceMesh verwendet wird !!!");
-    UBLOG(logINFO,"GbTriFaceMesh3D::deleteRedundantNodes !!! und darin die VertexTriFaceMap         !!!");
-    UBLOG(logINFO,"GbTriFaceMesh3D::deleteRedundantNodes !!! dann muss diese neu erzeugt werden     !!!");
-    UBLOG(logINFO,"GbTriFaceMesh3D::deleteRedundantNodes !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
+}
+/*======================================================================*/
+void GbTriFaceMesh3D::setKdTreeSplitAlgorithm(KDTREE_SPLITAGORITHM mode) 
+{ 
+   if(kdTree && mode != this->kdtreeSplitAlg) { delete kdTree; kdTree = NULL; }
+   this->kdtreeSplitAlg = mode; 
 }
 /*======================================================================*/
    /**
@@ -183,7 +288,10 @@ vector<GbTriFaceMesh3D::Vertex>* GbTriFaceMesh3D::getNodes()       {  return thi
  * @return the triangles of this triangular mesh
  */
 vector<GbTriFaceMesh3D::TriFace>* GbTriFaceMesh3D::getTriangles()  { return this->triangles;  }
-/*===============================================*/
+/**
+ * Returns the center x1 coordinate of this triangular mesh.
+ * @return the center x1 coordinate of this triangular mesh
+ */
 double GbTriFaceMesh3D::getVolume()
 {
    vector<Vertex>&  vertices = *nodes;
@@ -326,16 +434,18 @@ void GbTriFaceMesh3D::calculateValues()
       for(size_t i=1; i<this->nodes->size(); i++)
       {
          Vertex& v1 = (*nodes)[i];
+         
          x1min = UbMath::min<double>(x1min,v1.x);
-         x1max = UbMath::max<double>(x1max,v1.x);
          x2min = UbMath::min<double>(x2min,v1.y);
-         x2max = UbMath::max<double>(x2max,v1.y);
          x3min = UbMath::min<double>(x3min,v1.z);
+         
+         x1max = UbMath::max<double>(x1max,v1.x);
+         x2max = UbMath::max<double>(x2max,v1.y);
          x3max = UbMath::max<double>(x3max,v1.z);
       }
-      x1center = 0.5*(x1min+x1max);
-      x2center = 0.5*(x2min+x2max);
-      x3center = 0.5*(x3min+x3max);
+      x1center = 0.5 * (x1min + x1max );
+      x2center = 0.5 * (x2min + x2max );
+      x3center = 0.5 * (x3min + x3max );
       
       vector<TriFace>& tris  = *this->triangles;
       vector<Vertex>&  verts = *this->nodes;
@@ -355,45 +465,18 @@ void GbTriFaceMesh3D::calculateValues()
          }
       }
    }
-   this->consistent = true;
-
-   // Need to rebuild kd-tree.
-   kdTreeValid=false;
-}
-
-void GbTriFaceMesh3D::generateKdTree()
-{
-   //////////////////////////////////////////////////////////////////////////
-   //ACHTUNG: kdTree MUSS hier erfolgen (nach this->consistent = true; da der kdTree auf Methodes des GbTriFaceMesh zurück greift)
-   if (!consistent) calculateValues();
-
-   if( !nodes->empty() )
-   {
-      UBLOG(logDEBUG1, "GbTriFaceMesh3D::calculateValues - build KdTree start");
-
-      if(kdTree) delete kdTree;
-
-      UbTimer timer; timer.start();
-      if(kdtreeSplitAlg == KDTREE_SHAPLIT     ) 
-      {
-         UBLOG(logDEBUG1, "GbTriFaceMesh3D::calculateValues - build KdTree with SAHSplit");
-         this->kdTree = new Kd::Tree<double>( *this, Kd::SAHSplit<double>()            );
-      }
-      else if(kdtreeSplitAlg == KDTREE_SPATIALSPLIT)
-      {
-         UBLOG(logDEBUG1, "GbTriFaceMesh3D::calculateValues - build KdTree with SpatialMedianSplit");
-         this->kdTree = new Kd::Tree<double>( *this, Kd::SpatialMedianSplit<double>() ); 
-      }
-      else throw UbException(UB_EXARGS, "unknown kdtree split option)" );
-      std::cout<<"GbTriFaceMesh3D::calculateValues - built kdTree in "<<timer.stop()<<"seconds"<<std::endl;
-      //UBLOG(logDEBUG1, "GbTriFaceMesh3D::calculateValues - built kdTree in "<<timer.stop()<<"seconds");
+   if(kdTree)
+   { 
+      delete kdTree; 
+      kdTree=NULL; 
    }
-   kdTreeValid = true;
+   
+   this->consistent = true;
 }
 /*=========================================================================*/
 std::vector<GbTriFaceMesh3D::TriFace*> GbTriFaceMesh3D::getTrianglesForVertex(Vertex* vertex)
 {
-   if(!buildVertTriRelationMap) { buildVertTriRelationMap=true; consistent = false; }
+   if(!buildVertTriRelationMap) { buildVertTriRelationMap=true; consistent = false;}
    if(!consistent) this->calculateValues();
 
    typedef std::multimap<Vertex*,TriFace*>::iterator Iterator;
@@ -405,79 +488,71 @@ std::vector<GbTriFaceMesh3D::TriFace*> GbTriFaceMesh3D::getTrianglesForVertex(Ve
 
    return tmpTris;
 }
+/*=======================================================*/
+void GbTriFaceMesh3D::setCenterCoordinates(const double& x1, const double& x2, const double& x3) 
+{
+   this->translate(x1-getX1Centroid(), x2-getX2Centroid(), x3-getX3Centroid() );
+}
 
 /*======================================================================*/
-void GbTriFaceMesh3D::transform(const double matrix[4][4])
- {
-    if(!this->consistent) this->calculateValues();
-    vector<Vertex>& vertices = *nodes;
-    float tempX = 0.f;
-    float tempY = 0.f;
-    float tempZ = 0.f;
-
-    for(size_t i=0; i<vertices.size(); i++)
-    {
-       Vertex& v = vertices[i];
-       tempX = v.x;
-       tempY = v.y;
-       tempZ = v.z;
-       v.x = (float)(matrix[0][0] * tempX + matrix[0][1] * tempY + matrix[0][2] * tempZ + matrix[0][3] * 1.);
-       v.y = (float)(matrix[1][0] * tempX + matrix[1][1] * tempY + matrix[1][2] * tempZ + matrix[1][3] * 1.);
-       v.z = (float)(matrix[2][0] * tempX + matrix[2][1] * tempY + matrix[2][2] * tempZ + matrix[2][3] * 1.);
-    }
-    this->calculateValues();
-    this->notifyObserversObjectChanged();
- }
+void GbTriFaceMesh3D::scale(const double& sx1, const double& sx2, const double& sx3)
+{
+   CoordinateTransformation3D trafoForw(this->getX1Centroid(), this->getX2Centroid(), this->getX3Centroid(), 1.0, 1.0, 1.0, 0.0, 0.0, 0.0);
+   CoordinateTransformation3D trafoBack(this->getX1Centroid(), this->getX2Centroid(), this->getX3Centroid(), sx1, sx2, sx3, 0, 0, 0);
+
+   vector<Vertex>& vertices = *nodes;
+   for(size_t i=0; i<vertices.size(); i++)
+   {
+      Vertex& v = vertices[i];
+      double p1x1 = trafoForw.transformForwardToX1Coordinate(v.x, v.y, v.z);
+      double p1x2 = trafoForw.transformForwardToX2Coordinate(v.x, v.y, v.z);
+      double p1x3 = trafoForw.transformForwardToX3Coordinate(v.x, v.y, v.z);
+      v.x = (float)trafoBack.transformBackwardToX1Coordinate(p1x1, p1x2, p1x3);
+      v.y = (float)trafoBack.transformBackwardToX2Coordinate(p1x1, p1x2, p1x3);
+      v.z = (float)trafoBack.transformBackwardToX3Coordinate(p1x1, p1x2, p1x3);
+   }
+   this->calculateValues();
+}
 /*======================================================================*/
 void GbTriFaceMesh3D::rotate(const double& alpha, const double& beta, const double& gamma)
 {
-   if(!this->consistent) this->calculateValues();
-   double a1 = this->getX1Centroid();
-   double a2 = this->getX2Centroid();
-   double a3 = this->getX3Centroid();
-   CoordinateTransformation3D trafoFor(a1, a2, a3, 1.0, 1.0, 1.0, 0.0, 0.0, 0.0);
-   CoordinateTransformation3D trafoBack(a1, a2, a3, 1.0, 1.0, 1.0, alpha, beta, gamma);
+   CoordinateTransformation3D trafoForw(this->getX1Centroid(), this->getX2Centroid(), this->getX3Centroid(), 1.0, 1.0, 1.0, 0.0, 0.0, 0.0);
+   CoordinateTransformation3D trafoBack(this->getX1Centroid(), this->getX2Centroid(), this->getX3Centroid(), 1.0, 1.0, 1.0, alpha, beta, gamma);
 
    vector<Vertex>& vertices = *nodes;
    for(size_t i=0; i<vertices.size(); i++)
    {
       Vertex& v = vertices[i];
-      double p1x1 = trafoFor.transformForwardToX1Coordinate(v.x, v.y, v.z);
-      double p1x2 = trafoFor.transformForwardToX2Coordinate(v.x, v.y, v.z);
-      double p1x3 = trafoFor.transformForwardToX3Coordinate(v.x, v.y, v.z);
+      double p1x1 = trafoForw.transformForwardToX1Coordinate(v.x, v.y, v.z);
+      double p1x2 = trafoForw.transformForwardToX2Coordinate(v.x, v.y, v.z);
+      double p1x3 = trafoForw.transformForwardToX3Coordinate(v.x, v.y, v.z);
       v.x = (float)trafoBack.transformBackwardToX1Coordinate(p1x1, p1x2, p1x3);
       v.y = (float)trafoBack.transformBackwardToX2Coordinate(p1x1, p1x2, p1x3);
       v.z = (float)trafoBack.transformBackwardToX3Coordinate(p1x1, p1x2, p1x3);
    }
    this->calculateValues();
-   this->notifyObserversObjectChanged();
 }
-
 /*======================================================================*/
-void GbTriFaceMesh3D::scale(const double& sx1, const double& sx2, const double& sx3)
+void GbTriFaceMesh3D::rotateAroundPoint(const double& px1, const double& px2, const double& px3, const double& alpha, const double& beta, const double& gamma)
 {
-   if(!this->consistent) this->calculateValues();
-   double a1 = this->getX1Centroid();
-   double a2 = this->getX2Centroid();
-   double a3 = this->getX3Centroid();
-   CoordinateTransformation3D trafoFor(a1, a2, a3, 1.0, 1.0, 1.0, 0.0, 0.0, 0.0);
-   CoordinateTransformation3D trafoBack(a1, a2, a3, sx1, sx2, sx3, 0.0, 0.0, 0.0);
+   CoordinateTransformation3D trafoForw(px1, px2, px3, 1.0, 1.0, 1.0, 0.0, 0.0, 0.0);
+   CoordinateTransformation3D trafoBack(px1, px2, px3, 1.0, 1.0, 1.0, alpha, beta, gamma);
 
    vector<Vertex>& vertices = *nodes;
    for(size_t i=0; i<vertices.size(); i++)
    {
       Vertex& v = vertices[i];
-      double p1x1 = trafoFor.transformForwardToX1Coordinate(v.x, v.y, v.z);
-      double p1x2 = trafoFor.transformForwardToX2Coordinate(v.x, v.y, v.z);
-      double p1x3 = trafoFor.transformForwardToX3Coordinate(v.x, v.y, v.z);
+      double p1x1 = trafoForw.transformForwardToX1Coordinate(v.x, v.y, v.z);
+      double p1x2 = trafoForw.transformForwardToX2Coordinate(v.x, v.y, v.z);
+      double p1x3 = trafoForw.transformForwardToX3Coordinate(v.x, v.y, v.z);
       v.x = (float)trafoBack.transformBackwardToX1Coordinate(p1x1, p1x2, p1x3);
       v.y = (float)trafoBack.transformBackwardToX2Coordinate(p1x1, p1x2, p1x3);
       v.z = (float)trafoBack.transformBackwardToX3Coordinate(p1x1, p1x2, p1x3);
    }
    this->calculateValues();
-   this->notifyObserversObjectChanged();
 }
 
+
 /*======================================================================*/
 void GbTriFaceMesh3D::translate(const double& x1, const double& x2, const double& x3)
 {
@@ -485,17 +560,16 @@ void GbTriFaceMesh3D::translate(const double& x1, const double& x2, const double
    for(size_t i=0; i<vertices.size(); i++)
    {
       Vertex& v = vertices[i];
-      v.x+=static_cast<float>(x1);
-      v.y+=static_cast<float>(x2);
-      v.z+=static_cast<float>(x3);
+      v.x += static_cast<float>(x1);
+      v.y += static_cast<float>(x2);
+      v.z += static_cast<float>(x3);
    }
    this->calculateValues();
-   this->notifyObserversObjectChanged();
 }
 /*======================================================================*/
 vector<GbTriangle3D*> GbTriFaceMesh3D::getSurfaceTriangleSet()
 {
-   //SirAnn: eine miese Spciehrflochmethode
+   //SirAnn: eine miese Speicherlochmethode
    //        hier werden dynmamische Objekte angelegt 
    //        mit sowas rechnet von aussen kein Mensch!!!
    vector<GbTriangle3D*> tris( triangles->size() );
@@ -528,69 +602,327 @@ void GbTriFaceMesh3D::addSurfaceTriangleSet(vector<UbTupleFloat3>& pts, vector<U
    }
 }
 /*======================================================================*/
-bool GbTriFaceMesh3D::isPointInGbObject3D(const double& x1, const double& x2, const double& x3)
+//bool GbTriFaceMesh3D::isPointInGbObject3D(const double& x1, const double& x2, const double& x3, int counter)
+//{
+//
+//
+//   if( !nodes->empty() )
+//   {
+//      //Baum erstellen, wen noch keiner vorhanden
+//      if( !kdTree)
+//      {
+//         UBLOG(logDEBUG3, "GbTriFaceMesh3D::calculateValues - build KdTree start");
+//         UbTimer timer; timer.start();
+//         if(kdtreeSplitAlg == KDTREE_SAHPLIT     ) 
+//         {
+//            UBLOG(logDEBUG3, "GbTriFaceMesh3D::calculateValues - build KdTree with SAHSplit");
+//            this->kdTree = new Kd::Tree<double>( *this, Kd::SAHSplit<double>()            );
+//         }
+//         else if(kdtreeSplitAlg == KDTREE_SPATIALSPLIT)
+//         {
+//            UBLOG(logDEBUG3, "GbTriFaceMesh3D::calculateValues - build KdTree with SpatialMedianSplit");
+//            this->kdTree = new Kd::Tree<double>( *this, Kd::SpatialMedianSplit<double>() ); 
+//         }
+//         else throw UbException(UB_EXARGS, "unknown kdtree split option)" );
+//         UBLOG(logDEBUG3, "GbTriFaceMesh3D::calculateValues - built kdTree in "<<timer.stop()<<"seconds");
+//      }
+//
+//      //eigentlicher PIO-Test
+//      //int iSec;
+//      //for(int i=0; i<100; i++)
+//      //{
+//      //   Kd::Ray<double> ray(  x1, x2, x3  //, 1, 0 ,0 );
+//      //                        , ( x1 < x1center ? UbRandom::rand(-1.0,-0.001, 10) : UbRandom::rand(0.001, 1.0, 10) )
+//      //                        , ( x2 < x2center ? UbRandom::rand(-1.0,-0.001, 10) : UbRandom::rand(0.001, 1.0, 10) )
+//      //                        , ( x3 < x3center ? UbRandom::rand(-1.0,-0.001, 10) : UbRandom::rand(0.001, 1.0, 10) ) );
+//      //                        
+//      //   iSec = kdTree->intersectRay( ray, Kd::CountRayIntersectionHandler<double>() );
+//      //     
+//      //   if( iSec != Kd::Intersection::INTERSECT_EDGE ) //KEINE Kante getroffen
+//      //   {
+//      //      if(iSec == Kd::Intersection::ON_BOUNDARY )
+//      //      {
+//      //         return true;
+//      //      }
+//      //      return (iSec&1);  //ungerade anzahl an schnitten --> drinnen
+//      //   }
+//      //   UBLOG(logDEBUG3, "GbTriFaceMesh3D.isPointInGbObject3D.if  - an edge was hit ");
+//      //}
+//      //throw UbException(UB_EXARGS, "ups, nach 100 Strahlen immer noch kein Ergebnis");
+//      int iSec1,iSec2;
+//         
+//      Kd::Ray<double> ray1(  x1, x2, x3, 1.0, 0.0 ,0.0 );
+//      iSec1 = kdTree->intersectRay( ray1, Kd::CountRayIntersectionHandler<double>() );
+//      Kd::Ray<double> ray2(  x1, x2, x3, -1.0, 0.0 ,0.0 );
+//      iSec2 = kdTree->intersectRay( ray2, Kd::CountRayIntersectionHandler<double>() );
+//
+//      if(iSec1 == Kd::Intersection::ON_BOUNDARY || iSec2 == Kd::Intersection::ON_BOUNDARY)
+//      {
+//         return true;
+//      }
+//      if( iSec1 == Kd::Intersection::INTERSECT_EDGE && iSec2 == Kd::Intersection::INTERSECT_EDGE) 
+//      {
+//         UBLOG(logINFO, "GbTriFaceMesh3D.isPointInGbObject3D.INTERSECT_EDGE");
+//         double eps = UbMath::getEqualityEpsilon<float>()*1000.0;
+//         if (counter>100) {return(iSec1&1);  UBLOG(logINFO, "NACH 100 Iterationen Eps umsetzen aufgegeben!");}
+//         return this->isPointInGbObject3D(x1+eps, x2+eps, x3+eps,(counter+1)); 
+//      }
+//      else if( iSec1 == Kd::Intersection::INTERSECT_EDGE)
+//      {
+//         return (iSec2&1);  
+//      }
+//      else if( iSec2 == Kd::Intersection::INTERSECT_EDGE)
+//      {
+//         return (iSec1&1);  
+//      }
+//      else
+//      {
+//         if((iSec1&1) != (iSec2&1))
+//         {
+//            UBLOG(logINFO, "GbTriFaceMesh3D.isPointInGbObject3D.iSec1&1 != iSec2&1");
+//            double eps = UbMath::getEqualityEpsilon<float>()*1000.0;
+//            if (counter>100) {return(iSec1&1);  UBLOG(logINFO, "NACH 100 Iterationen Eps umsetzen aufgegeben!");}
+//            return this->isPointInGbObject3D(x1+eps, x2+eps, x3+eps,(counter+1));
+//         }
+//         return iSec1&1;
+//      }
+//      //throw UbException(UB_EXARGS, "ups, nach 100 Strahlen immer noch kein Ergebnis");
+//
+//   }
+//   return false;
+//}
+bool GbTriFaceMesh3D::isPointInGbObject3D(const double& x1, const double& x2, const double& x3, int counter)
 {
-   if (!kdTreeValid) generateKdTree();
 
-   int iSec;
-   for(int i=0; i<100; i++)
+
+   if( !nodes->empty() )
    {
-      Kd::Ray<double> ray(  x1, x2, x3  //, 1, 0 ,0 );
-                           , ( x1 < x1center ? UbRandom::rand(-1.0,-0.001, 10) : UbRandom::rand(0.001, 1.0, 10) )
-                           , ( x2 < x2center ? UbRandom::rand(-1.0,-0.001, 10) : UbRandom::rand(0.001, 1.0, 10) )
-                           , ( x3 < x3center ? UbRandom::rand(-1.0,-0.001, 10) : UbRandom::rand(0.001, 1.0, 10) ) );
-        
-      iSec = kdTree->intersectRay( ray, Kd::CountRayIntersectionHandler<double>() );
-        
-      if( iSec != Kd::Intersection::INTERSECT_EDGE ) //KEINE Kante getroffen
+      //Baum erstellen, wen noch keiner vorhanden
+      if( !kdTree)
       {
-         if(iSec == Kd::Intersection::ON_BOUNDARY )
+         UBLOG(logDEBUG3, "GbTriFaceMesh3D::calculateValues - build KdTree start");
+         UbTimer timer; timer.start();
+         if(kdtreeSplitAlg == KDTREE_SAHPLIT     ) 
          {
-            return true;
+            UBLOG(logDEBUG3, "GbTriFaceMesh3D::calculateValues - build KdTree with SAHSplit");
+            this->kdTree = new Kd::Tree<double>( *this, Kd::SAHSplit<double>()            );
          }
-         return (iSec&1);  //ungerade anzahl an schnitten --> drinnen
+         else if(kdtreeSplitAlg == KDTREE_SPATIALSPLIT)
+         {
+            UBLOG(logDEBUG3, "GbTriFaceMesh3D::calculateValues - build KdTree with SpatialMedianSplit");
+            this->kdTree = new Kd::Tree<double>( *this, Kd::SpatialMedianSplit<double>() ); 
+         }
+         else throw UbException(UB_EXARGS, "unknown kdtree split option)" );
+         UBLOG(logDEBUG3, "GbTriFaceMesh3D::calculateValues - built kdTree in "<<timer.stop()<<"seconds");
+      }
+
+      //eigentlicher PIO-Test
+      //int iSec;
+      //for(int i=0; i<100; i++)
+      //{
+      //   Kd::Ray<double> ray(  x1, x2, x3  //, 1, 0 ,0 );
+      //                        , ( x1 < x1center ? UbRandom::rand(-1.0,-0.001, 10) : UbRandom::rand(0.001, 1.0, 10) )
+      //                        , ( x2 < x2center ? UbRandom::rand(-1.0,-0.001, 10) : UbRandom::rand(0.001, 1.0, 10) )
+      //                        , ( x3 < x3center ? UbRandom::rand(-1.0,-0.001, 10) : UbRandom::rand(0.001, 1.0, 10) ) );
+      //                        
+      //   iSec = kdTree->intersectRay( ray, Kd::CountRayIntersectionHandler<double>() );
+      //     
+      //   if( iSec != Kd::Intersection::INTERSECT_EDGE ) //KEINE Kante getroffen
+      //   {
+      //      if(iSec == Kd::Intersection::ON_BOUNDARY )
+      //      {
+      //         return true;
+      //      }
+      //      return (iSec&1);  //ungerade anzahl an schnitten --> drinnen
+      //   }
+      //   UBLOG(logDEBUG3, "GbTriFaceMesh3D.isPointInGbObject3D.if  - an edge was hit ");
+      //}
+      //throw UbException(UB_EXARGS, "ups, nach 100 Strahlen immer noch kein Ergebnis");
+      int iSec1,iSec2;
+      double eps = 0.05;        
+      Kd::Ray<double> ray1(  x1, x2, x3, 1.0+eps*((double)counter), eps*((double)counter) ,eps*((double)counter) );
+      iSec1 = kdTree->intersectRay( ray1, Kd::CountRayIntersectionHandler<double>() );
+      Kd::Ray<double> ray2(  x1, x2, x3, -1.0-eps*((double)counter), -eps*((double)counter) ,-eps*((double)counter) );
+ 
+      iSec2 = kdTree->intersectRay( ray2, Kd::CountRayIntersectionHandler<double>() );
+
+      if(iSec1 == Kd::Intersection::ON_BOUNDARY || iSec2 == Kd::Intersection::ON_BOUNDARY)
+      {
+         return true;
+      }
+      if( iSec1 == Kd::Intersection::INTERSECT_EDGE && iSec2 == Kd::Intersection::INTERSECT_EDGE) 
+      {
+         //UBLOG(logINFO, "GbTriFaceMesh3D.isPointInGbObject3D.INTERSECT_EDGE");
+
+         if (counter>20) {return(iSec1&1);  UBLOG(logINFO, "NACH 100 Iterationen Eps umsetzen aufgegeben!");}
+         return this->isPointInGbObject3D(x1, x2, x3,(counter+1)); 
+      }
+      else if( iSec1 == Kd::Intersection::INTERSECT_EDGE)
+      {
+         return (iSec2&1);  
       }
-      UBLOG(logWARNING, "GbTriFaceMesh3D.isPointInGbObject3D.if  - an edge was hit ");
+      else if( iSec2 == Kd::Intersection::INTERSECT_EDGE)
+      {
+         return (iSec1&1);  
+      }
+      else
+      {
+         if((iSec1&1) != (iSec2&1))
+         {
+            //UBLOG(logINFO, "GbTriFaceMesh3D.isPointInGbObject3D.iSec1&1 != iSec2&1");
+
+            if (counter>20) {return(iSec1&1);  UBLOG(logINFO, "NACH 100 Iterationen Eps umsetzen aufgegeben!");}
+            return this->isPointInGbObject3D(x1, x2, x3,(counter+1));
+         }
+         return iSec1&1;
+      }
+      //throw UbException(UB_EXARGS, "ups, nach 100 Strahlen immer noch kein Ergebnis");
+
    }
-   throw UbException(UB_EXARGS, "ups, nach 100 Strahlen immer noch kein Ergebnis");
+   return false;
 }
 /*======================================================================*/
-bool GbTriFaceMesh3D::isPointInGbObject3D(const double& x1, const double& x2, const double& x3, bool& pointIsOnBoundary)
+bool GbTriFaceMesh3D::isPointInGbObject3D(const double& x1, const double& x2, const double& x3)
 {
-   if (!kdTreeValid) generateKdTree();
-   
-   int iSec;
-   for(int i=0; i<100; i++)
-   {
-      Kd::Ray<double> ray(  x1, x2, x3 
-                         , float( ( x1 < x1center ? UbRandom::rand(-1.0,-0.001, 10) : UbRandom::rand(0.001, 1.0, 10) ) )
-                         , float( ( x2 < x2center ? UbRandom::rand(-1.0,-0.001, 10) : UbRandom::rand(0.001, 1.0, 10) ) )
-                         , float( ( x3 < x3center ? UbRandom::rand(-1.0,-0.001, 10) : UbRandom::rand(0.001, 1.0, 10) ) ) );
+  int counter=0;
 
-      iSec = kdTree->intersectRay( ray, Kd::CountRayIntersectionHandler<double>()    );
+   if( !nodes->empty() )
+   {
+      //Baum erstellen, wen noch keiner vorhanden
+      if( !kdTree)
+      {
+         UBLOG(logDEBUG3, "GbTriFaceMesh3D::calculateValues - build KdTree start");
+         UbTimer timer; timer.start();
+         if(kdtreeSplitAlg == KDTREE_SAHPLIT     ) 
+         {
+            UBLOG(logDEBUG3, "GbTriFaceMesh3D::calculateValues - build KdTree with SAHSplit");
+            this->kdTree = new Kd::Tree<double>( *this, Kd::SAHSplit<double>()            );
+         }
+         else if(kdtreeSplitAlg == KDTREE_SPATIALSPLIT)
+         {
+            UBLOG(logDEBUG3, "GbTriFaceMesh3D::calculateValues - build KdTree with SpatialMedianSplit");
+            this->kdTree = new Kd::Tree<double>( *this, Kd::SpatialMedianSplit<double>() ); 
+         }
+         else throw UbException(UB_EXARGS, "unknown kdtree split option)" );
+         UBLOG(logDEBUG3, "GbTriFaceMesh3D::calculateValues - built kdTree in "<<timer.stop()<<"seconds");
+      }
 
-      if( iSec != Kd::Intersection::INTERSECT_EDGE ) //KEINE Kante getroffen
+      //eigentlicher PIO-Test
+      int iSec;
+      for(int i=0; i<MAX_ITER; i++)
       {
-         if(iSec == Kd::Intersection::ON_BOUNDARY )
+         Kd::Ray<double> ray(  x1, x2, x3  //, 1, 0 ,0 );
+                              , ( x1 < x1center ? UbRandom::rand(-1.0,-0.001, 10) : UbRandom::rand(0.001, 1.0, 10) )
+                              , ( x2 < x2center ? UbRandom::rand(-1.0,-0.001, 10) : UbRandom::rand(0.001, 1.0, 10) )
+                              , ( x3 < x3center ? UbRandom::rand(-1.0,-0.001, 10) : UbRandom::rand(0.001, 1.0, 10) ) );
+                              
+         iSec = kdTree->intersectRay( ray, Kd::CountRayIntersectionHandler<double>() );
+           
+         if( iSec != Kd::Intersection::INTERSECT_EDGE ) //KEINE Kante getroffen
          {
-            pointIsOnBoundary = true;
-            return true;
+            if(iSec == Kd::Intersection::ON_BOUNDARY )
+            {
+               return true;
+            }
+            return (iSec&1);  //ungerade anzahl an schnitten --> drinnen
          }
-         pointIsOnBoundary = false;
-         return (iSec&1);  //ungerade anzahl an schnitten --> drinnen
+         UBLOG(logDEBUG3, "GbTriFaceMesh3D.isPointInGbObject3D.if  - an edge was hit ");
       }
-   }
+      throw UbException(UB_EXARGS, "ups, nach 100 Strahlen immer noch kein Ergebnis");
+
+   //   int iSec1,iSec2;
+   //      
+   //   Kd::Ray<double> ray1(  x1, x2, x3, 1.0, 0.0 ,0.0 );
+   //   iSec1 = kdTree->intersectRay( ray1, Kd::CountRayIntersectionHandler<double>() );
+   //   Kd::Ray<double> ray2(  x1, x2, x3, -1.0, 0.0 ,0.0 );
+   //   iSec2 = kdTree->intersectRay( ray2, Kd::CountRayIntersectionHandler<double>() );
+
+   //   if(iSec1 == Kd::Intersection::ON_BOUNDARY || iSec2 == Kd::Intersection::ON_BOUNDARY)
+   //   {
+   //      return true;
+   //   }
+   //   if( iSec1 == Kd::Intersection::INTERSECT_EDGE && iSec2 == Kd::Intersection::INTERSECT_EDGE) 
+   //   {
+   //      //UBLOG(logINFO, "GbTriFaceMesh3D.isPointInGbObject3D.INTERSECT_EDGE");
+   //      double eps = UbMath::getEqualityEpsilon<double>();
+   //      if (counter>100) {return(iSec1&1);  UBLOG(logINFO, "NACH 100 Iterationen Eps umsetzen aufgegeben!");}
+   //      return this->isPointInGbObject3D(x1+eps, x2+eps, x3+eps,(counter+1)); 
+   //   }
+   //   else if( iSec1 == Kd::Intersection::INTERSECT_EDGE)
+   //   {
+   //      return (iSec2&1);  
+   //   }
+   //   else if( iSec2 == Kd::Intersection::INTERSECT_EDGE)
+   //   {
+   //      return (iSec1&1);  
+   //   }
+   //   else
+   //   {
+   //      if((iSec1&1) != (iSec2&1))
+   //      {
+   //         UBLOG(logINFO, "GbTriFaceMesh3D.isPointInGbObject3D.iSec1&1 != iSec2&1");
+   //         double eps = UbMath::getEqualityEpsilon<double>();
+   //         if (counter>100) {return(iSec1&1);  UBLOG(logINFO, "NACH 100 Iterationen Eps umsetzen aufgegeben!");}
+   //         return this->isPointInGbObject3D(x1+eps, x2+eps, x3+eps,(counter+1));
+   //      }
+   //      return iSec1&1;
+   //   }
+   //   //throw UbException(UB_EXARGS, "ups, nach 100 Strahlen immer noch kein Ergebnis");
 
-   throw UbException(UB_EXARGS, "ups, nach 100 Strahlen immer noch kein Ergebnis");
+   }
+   return false;
 }
 /*======================================================================*/
-bool GbTriFaceMesh3D::intersectLine(const double& p1_x1, const double& p1_x2, const double& p1_x3, const double& p2_x1, const double& p2_x2, const double& p2_x3)
+bool GbTriFaceMesh3D::isPointInGbObject3D(const double& x1, const double& x2, const double& x3, bool& pointIsOnBoundary)
 {
-   if (!kdTreeValid) generateKdTree();
+   if( !nodes->empty() )
+   {
+      //Baum erstellen, wen noch keiner vorhanden
+      if( !kdTree)
+      {
+         UBLOG(logDEBUG3, "GbTriFaceMesh3D::calculateValues - build KdTree start");
+         UbTimer timer; timer.start();
+         if(kdtreeSplitAlg == KDTREE_SAHPLIT     ) 
+         {
+            UBLOG(logDEBUG3, "GbTriFaceMesh3D::calculateValues - build KdTree with SAHSplit");
+            this->kdTree = new Kd::Tree<double>( *this, Kd::SAHSplit<double>()            );
+         }
+         else if(kdtreeSplitAlg == KDTREE_SPATIALSPLIT)
+         {
+            UBLOG(logDEBUG3, "GbTriFaceMesh3D::calculateValues - build KdTree with SpatialMedianSplit");
+            this->kdTree = new Kd::Tree<double>( *this, Kd::SpatialMedianSplit<double>() ); 
+         }
+         else throw UbException(UB_EXARGS, "unknown kdtree split option)" );
+         UBLOG(logDEBUG3, "GbTriFaceMesh3D::calculateValues - built kdTree in "<<timer.stop()<<"seconds");
+      }
 
-   int iSec = kdTree->intersectLine( UbTupleDouble3(p1_x1, p1_x2, p1_x3), UbTupleDouble3(p2_x1, p2_x2, p2_x3), Kd::CountLineIntersectionHandler<double>() );
+      //eigentlicher PIO-Test
+      int iSec;
+      for(int i=0; i<MAX_ITER; i++)
+      {
+         Kd::Ray<double> ray(  x1, x2, x3 
+                            , float( ( x1 < x1center ? UbRandom::rand(-1.0,-0.001, 10) : UbRandom::rand(0.001, 1.0, 10) ) )
+                            , float( ( x2 < x2center ? UbRandom::rand(-1.0,-0.001, 10) : UbRandom::rand(0.001, 1.0, 10) ) )
+                            , float( ( x3 < x3center ? UbRandom::rand(-1.0,-0.001, 10) : UbRandom::rand(0.001, 1.0, 10) ) ) );
+
+         iSec = kdTree->intersectRay( ray, Kd::CountRayIntersectionHandler<double>()    );
+
+         if( iSec != Kd::Intersection::INTERSECT_EDGE ) //KEINE Kante getroffen
+         {
+            if(iSec == Kd::Intersection::ON_BOUNDARY )
+            {
+               pointIsOnBoundary = true;
+               return true;
+            }
+            pointIsOnBoundary = false;
+            return (iSec&1);  //ungerade anzahl an schnitten --> drinnen
+         }
+      }
 
-   return (iSec != Kd::Intersection::NO_INTERSECTION);
+      throw UbException(UB_EXARGS, "ups, nach 100 Strahlen immer noch kein Ergebnis");
+   }
+   
+   return false;
 }
 /*======================================================================*/
 GbLine3D* GbTriFaceMesh3D::createClippedLine3D (GbPoint3D& point1, GbPoint3D& point2)
@@ -601,69 +933,96 @@ GbLine3D* GbTriFaceMesh3D::createClippedLine3D (GbPoint3D& point1, GbPoint3D& po
 void GbTriFaceMesh3D::write(UbFileOutput* out)
 {
    out->writeString(this->getCreator()->getTypeID());
-   
    out->writeInteger((int)kdtreeSplitAlg);
+   out->writeBool(transferViaFilename);
 
-   //nodes
-   vector<Vertex>& vertices = *nodes;
-   out->writeSize_t( nodes->size() );
-   out->writeLine();
-   for(size_t i=0; i<vertices.size(); i++)
+   if(!transferViaFilename)
    {
-      Vertex& v = vertices[i];
-      out->writeFloat(v.x);
-      out->writeFloat(v.y);
-      out->writeFloat(v.z);
+      //nodes
+      vector<Vertex>& vertices = *nodes;
+      out->writeSize_t( nodes->size() );
       out->writeLine();
+      for(size_t i=0; i<vertices.size(); i++)
+      {
+         Vertex& v = vertices[i];
+         out->writeFloat(v.x);
+         out->writeFloat(v.y);
+         out->writeFloat(v.z);
+         out->writeLine();
+      }
+      
+      //triangles
+      vector<TriFace>& tris = *triangles;
+      out->writeSize_t( tris.size() );
+      out->writeLine();
+      for(size_t i=0; i<tris.size(); i++)
+      {
+         TriFace& t = tris[i];
+         out->writeInteger(t.v1);
+         out->writeInteger(t.v2);
+         out->writeInteger(t.v3);
+         out->writeLine();
+      }
    }
-   
-   //triangles
-   vector<TriFace>& tris = *triangles;
-   out->writeSize_t( tris.size() );
-   out->writeLine();
-   for(size_t i=0; i<tris.size(); i++)
+   else
    {
-      TriFace& t = tris[i];
-      out->writeInteger(t.v1);
-      out->writeInteger(t.v2);
-      out->writeInteger(t.v3);
+      out->writeString(filename);
       out->writeLine();
+      out->writeDouble(transX1);
+      out->writeDouble(transX2);
+      out->writeDouble(transX3);
+
    }
 }
 /*======================================================================*/
 void GbTriFaceMesh3D::read(UbFileInput* in)
 {
    kdtreeSplitAlg =  (KDTREE_SPLITAGORITHM)in->readInteger();
+   transferViaFilename = in->readBool();
 
-   if(!nodes) nodes = new vector<Vertex>;
-   //nodes
-   vector<Vertex>& vertices = *nodes;
-   vertices.resize( in->readSize_t( ) );
-   in->readLine();
-   for(size_t i=0; i<vertices.size(); i++)
+   if(!transferViaFilename)
    {
-      Vertex& v = vertices[i];
-      v.x = in->readFloat();
-      v.y = in->readFloat();
-      v.z = in->readFloat();
+      if(!nodes) nodes = new vector<Vertex>;
+      //nodes
+      vector<Vertex>& vertices = *nodes;
+      vertices.resize( in->readSize_t( ) );
       in->readLine();
-   }
+      for(size_t i=0; i<vertices.size(); i++)
+      {
+         Vertex& v = vertices[i];
+         v.x = in->readFloat();
+         v.y = in->readFloat();
+         v.z = in->readFloat();
+         in->readLine();
+      }
 
-   //triangles
-   if(!triangles) triangles = new vector<TriFace>;
-   vector<TriFace>& tris = *triangles;
-   tris.resize( in->readSize_t( ) );
-   in->readLine();
-   for(size_t i=0; i<tris.size(); i++)
-   {
-      TriFace& t = tris[i];
-      t.v1 = in->readInteger();
-      t.v2 = in->readInteger();
-      t.v3 = in->readInteger();
+      //triangles
+      if(!triangles) triangles = new vector<TriFace>;
+      vector<TriFace>& tris = *triangles;
+      tris.resize( in->readSize_t( ) );
       in->readLine();
+      for(size_t i=0; i<tris.size(); i++)
+      {
+         TriFace& t = tris[i];
+         t.v1 = in->readInteger();
+         t.v2 = in->readInteger();
+         t.v3 = in->readInteger();
+         in->readLine();
+      }
+
+      this->calculateValues();
    }
+   else
+   {
+      filename = in->readString();
+      in->readLine();
+      transX1 = in->readDouble();
+      transX2 = in->readDouble();
+      transX3 = in->readDouble();
 
-   this->calculateValues();
+      this->readMeshFromSTLFile(filename, true);
+      this->translate(transX1,transX2,transX3);
+   }
 }
 /*======================================================================*/
 UbTuple<string, string> GbTriFaceMesh3D::writeMesh(string filename, WbWriter* writer, bool writeNormals, vector< string >* datanames, std::vector< std::vector < double > >* nodedata )
@@ -700,9 +1059,10 @@ UbTuple<string, string> GbTriFaceMesh3D::writeMesh(string filename, WbWriter* wr
          lineNodes[i*2  ] = makeUbTuple( triangle.getX1Centroid(*nodes)
                                         ,triangle.getX2Centroid(*nodes)
                                         ,triangle.getX3Centroid(*nodes));
-         lineNodes[i*2+1] = makeUbTuple( (float)(triangle.getX1Centroid(*nodes)+1.*triangle.nx)
-                                        ,(float)(triangle.getX2Centroid(*nodes)+1.*triangle.ny)
-                                        ,(float)(triangle.getX3Centroid(*nodes)+1.*triangle.nz));
+
+         lineNodes[i*2+1] = makeUbTuple( (float)(triangle.getX1Centroid(*nodes)+1.0*triangle.nx)
+                                        ,(float)(triangle.getX2Centroid(*nodes)+1.0*triangle.ny)
+                                        ,(float)(triangle.getX3Centroid(*nodes)+1.0*triangle.nz));
 
          lines[i] = makeUbTuple((int)i*2,(int)i*2+1);
       }
@@ -712,3 +1072,156 @@ UbTuple<string, string> GbTriFaceMesh3D::writeMesh(string filename, WbWriter* wr
    return filenames;
 }
 /*======================================================================*/
+void GbTriFaceMesh3D::writeMeshPly( const std::string& filename)
+{
+   ofstream out(filename.c_str() );
+   if( !out )
+      throw UbException(UB_EXARGS, "couldn't open " + filename);
+
+   out << "ply" << endl;
+   out << "format ascii 1.0" << endl;
+   out << "element vertex " << (int)nodes->size() << endl;
+   out << "property float x" << endl;
+   out << "property float y" << endl;
+   out << "property float z" << endl;
+   out << "element face " << (int)triangles->size() << endl;
+   out << "property list uchar int vertex_indices" << endl;
+   out << "end_header" << endl;
+
+   for(size_t i=0; i<nodes->size(); i++)
+      out << (*nodes)[i].x << " " << (*nodes)[i].y << " " << (*nodes)[i].z << endl;
+
+   for(size_t i=0; i<triangles->size(); i++)
+      out << "3 " << (*triangles)[i].v1 << " " << (*triangles)[i].v2 << " " << (*triangles)[i].v3 << endl;
+}
+/*======================================================================*/
+void GbTriFaceMesh3D::readMeshFromSTLFile(string filename, bool removeRedundantNodes)
+{
+   UBLOG(logDEBUG1,"GbTriFaceMesh3DCreator::readMeshFromSTLFile !!! Dieses Format hat leider redundante Knoten ...");
+
+   UbFileInputASCII in(filename);
+   //this->nodes     = new vector<GbTriFaceMesh3D::Vertex>;
+   //this->triangles = new vector<GbTriFaceMesh3D::TriFace>;
+   string dummy;
+
+   double x, y, z;
+   int nr=0;
+
+   in.readLine();
+   while(dummy!="endsolid")
+   {
+      in.readLine();
+      in.readLine();
+      dummy = in.readString();
+      if(dummy!="vertex") throw UbException(UB_EXARGS,"no vertex format");
+      x=in.readDouble();
+      y=in.readDouble();
+      z=in.readDouble();
+      nodes->push_back(GbTriFaceMesh3D::Vertex((float)x,(float)y,(float)z));
+      in.readLine();
+      in.readString();
+      x=in.readDouble();
+      y=in.readDouble();
+      z=in.readDouble();
+      nodes->push_back(GbTriFaceMesh3D::Vertex((float)x,(float)y,(float)z));
+      in.readLine();
+      in.readString();
+      x=in.readDouble();
+      y=in.readDouble();
+      z=in.readDouble();
+      nodes->push_back(GbTriFaceMesh3D::Vertex((float)x,(float)y,(float)z));
+      triangles->push_back(GbTriFaceMesh3D::TriFace(nr,nr+1,nr+2));
+      in.readLine();
+      in.readLine();
+      in.readLine();
+      dummy = in.readString();
+      nr+=3;
+   }
+   if(removeRedundantNodes)
+   {
+      this->deleteRedundantNodes(); //dort wird autoamtisch calculateValues() aufgerufen
+   }
+   else
+   {
+      this->calculateValues();
+   }
+}
+//////////////////////////////////////////////////////////////////////////
+//void GbTriFaceMesh3D::writeMeshToSTLFile(string filename, bool isBinaryFormat)
+//{
+//   vector<GbTriFaceMesh3D::Vertex>    *nodes     = new vector<GbTriFaceMesh3D::Vertex>;
+//   vector<GbTriFaceMesh3D::TriFace>   *triangles = new vector<GbTriFaceMesh3D::TriFace>;
+//   int nr=0;
+//
+//   if (!isBinaryFormat) {
+//      ofstream out(filename.c_str());
+//      if (!out.good())
+//      {
+//         delete nodes;
+//         delete triangles;
+//         UB_THROW(UbException(UB_EXARGS, "Can not open STL file: "+filename));
+//      }
+//      char title[80] = "ASCII";
+//      std::string s0, s1;
+//      float n0, n1, n2, f0, f1, f2, f3, f4, f5, f6, f7, f8;
+//      out.write(title, 80);
+//      size_t size = nodes->size();
+//      for (size_t i = 0; i < size)
+//      {
+//         out << nodes[i++]
+//         in >> s0;                                // facet || endsolid
+//         if (s0=="facet") {
+//            in >> s1 >> n0 >> n1 >> n2;            // normal x y z
+//            in >> s0 >> s1;                        // outer loop
+//            in >> s0 >> f0 >> f1 >> f2;         // vertex x y z
+//            in >> s0 >> f3 >> f4 >> f5;         // vertex x y z
+//            in >> s0 >> f6 >> f7 >> f8;         // vertex x y z
+//            in >> s0;                            // endloop
+//            in >> s0;                            // endfacet
+//            // Generate a new Triangle without Normal as 3 Vertices
+//            nodes->push_back(GbTriFaceMesh3D::Vertex(f0, f1, f2));
+//            nodes->push_back(GbTriFaceMesh3D::Vertex(f3, f4, f5));
+//            nodes->push_back(GbTriFaceMesh3D::Vertex(f6, f7, f8));
+//            triangles->push_back(GbTriFaceMesh3D::TriFace(nr, nr+1, nr+2));
+//            nr+=3;
+//         }
+//         else if (s0=="endsolid") {
+//            break;
+//         }
+//      }
+//      in.close();
+//   }
+//   else {
+//      FILE *f = fopen(filename.c_str(), "rb");
+//      if (!f)
+//      {
+//         delete nodes;
+//         delete triangles;
+//         UB_THROW(UbException(UB_EXARGS, "Can not open STL file: "+filename));
+//      }
+//      char title[80];
+//      int nFaces;
+//      fread(title, 80, 1, f);
+//      fread((void*)&nFaces, 4, 1, f);
+//      float v[12]; // normal=3, vertices=3*3 = 12
+//      unsigned short uint16;
+//      // Every Face is 50 Bytes: Normal(3*float), Vertices(9*float), 2 Bytes Spacer
+//      for (size_t i=0; i<nFaces; ++i) {
+//         for (size_t j=0; j<12; ++j) {
+//            fread((void*)&v[j], sizeof(float), 1, f);
+//         }
+//         fread((void*)&uint16, sizeof(unsigned short), 1, f); // spacer between successive faces
+//         nodes->push_back(GbTriFaceMesh3D::Vertex(v[3], v[4], v[5]));
+//         nodes->push_back(GbTriFaceMesh3D::Vertex(v[6], v[7], v[8]));
+//         nodes->push_back(GbTriFaceMesh3D::Vertex(v[9], v[10], v[11]));
+//         triangles->push_back(GbTriFaceMesh3D::TriFace(nr, nr+1, nr+2));
+//         nr+=3;
+//      }
+//      fclose(f);
+//   }
+//
+//   GbTriFaceMesh3D* mesh = new GbTriFaceMesh3D(meshName, nodes, triangles, splitAlg, removeRedundantNodes);
+//
+//   return mesh;
+//}
+//////////////////////////////////////////////////////////////////////////
diff --git a/src/VirtualFluidsBasics/numerics/geometry3d/GbTriFaceMesh3D.h b/src/VirtualFluidsBasics/numerics/geometry3d/GbTriFaceMesh3D.h
index 470c31eeef1ecc83d4fa11357b257ad6452f8237..96b18593c75f891390138421073f5d8da73cbc4b 100644
--- a/src/VirtualFluidsBasics/numerics/geometry3d/GbTriFaceMesh3D.h
+++ b/src/VirtualFluidsBasics/numerics/geometry3d/GbTriFaceMesh3D.h
@@ -10,18 +10,23 @@
 #include <sstream>
 #include <iostream>
 #include <vector>
-#include <map>
 
-#include <VirtualFluidsDefinitions.h>
+#ifdef CAB_RCF
+   #include <3rdParty/rcf/RcfSerializationIncludes.h>
+#endif //CAB_RCF
+
 
 #include <basics/utilities/UbException.h>
 #include <basics/utilities/UbMath.h>
+#include <basics/utilities/Vector3D.h>
+#include <basics/writer/WbWriter.h>
 
+#include <basics/memory/MbSmartPtr.h>
 
-#include "basics/utilities/Vector3D.h"
-#include "GbObject3D.h"
+#include <numerics/geometry3d/GbPoint3D.h> 
+
+#include <VirtualFluidsDefinitions.h>
 
-class WbWriter;
 
 namespace Kd 
 { 
@@ -30,9 +35,6 @@ namespace Kd
    template< typename T > class RayIntersectionHandler;
 }
 
-//RayCrossing Test ...
-//http://orion.math.iastate.edu/burkardt/c_src/orourke/inhedron.c
-
 
 /*=========================================================================*/
 /* GbTriFaceMesh3D                                                                  */
@@ -75,7 +77,7 @@ public:
       }
       bool operator== (const Vertex& rhs)
       {
-         return ( fabs(x-rhs.x)<1.E-10 && fabs(y-rhs.y)<1.E-10 && fabs(z-rhs.z)<1.E-10 );
+         return ( fabs(x-rhs.x)<1.E-8 && fabs(y-rhs.y)<1.E-8 && fabs(z-rhs.z)<1.E-8 );
       }
       friend inline bool operator<(const Vertex & lhsVert,const Vertex & rhsVert)
       {
@@ -96,12 +98,6 @@ public:
          return(new Vertex(this));
       }
 
-      template<class Archive>
-      void serialize(Archive & ar, const unsigned int version)
-      {
-         ar & x & y & z;
-      }
-
 #ifdef CAB_RCF
       template<class Archive>
       void SF_SERIALIZE(Archive & ar)
@@ -189,12 +185,12 @@ public:
          //GbVector3D AC = C-A;
          //GbVector3D N = AB.Cross(AC);
          //return 0.5*N.Length();
-          Vector3D A(nodes[v1].x, nodes[v1].y, nodes[v1].z);
-          Vector3D B(nodes[v2].x, nodes[v2].y, nodes[v2].z);
-          Vector3D C(nodes[v3].x, nodes[v3].y, nodes[v3].z);
-          Vector3D AB = B - A;
-          Vector3D AC = C - A;
-          Vector3D N = AB.Cross(AC);
+         Vector3D A(nodes[v1].x, nodes[v1].y, nodes[v1].z);
+         Vector3D B(nodes[v2].x, nodes[v2].y, nodes[v2].z);
+         Vector3D C(nodes[v3].x, nodes[v3].y, nodes[v3].z);
+         Vector3D AB = B-A;
+         Vector3D AC = C-A;
+         Vector3D N = AB.Cross(AC);
          return 0.5*N.Length();
       }
       void calculateNormal(std::vector<Vertex>& nodes)
@@ -222,13 +218,6 @@ public:
                      <<"->removeRedunantNodes"<<std::endl;
          }
       }
-
-      template<class Archive>
-      void serialize(Archive & ar, const unsigned int version)
-      {
-         ar & v1 & v2 & v3;
-      }
-
    #ifdef CAB_RCF
       template<class Archive>
       void SF_SERIALIZE(Archive & ar)
@@ -243,14 +232,14 @@ public:
    };
 
 public:
-  enum KDTREE_SPLITAGORITHM { KDTREE_SHAPLIT, KDTREE_SPATIALSPLIT };
+  enum KDTREE_SPLITAGORITHM { KDTREE_SAHPLIT, KDTREE_SPATIALSPLIT };
 
 public:
    GbTriFaceMesh3D();
-   GbTriFaceMesh3D(std::string name, std::vector<Vertex>* nodes, std::vector<TriFace>* triangles, KDTREE_SPLITAGORITHM splitAlg = KDTREE_SHAPLIT, bool removeRedundantNodes=true);
+   GbTriFaceMesh3D(std::string name, std::vector<Vertex>* nodes, std::vector<TriFace>* triangles, KDTREE_SPLITAGORITHM splitAlg = KDTREE_SAHPLIT, bool removeRedundantNodes=true);
 	~GbTriFaceMesh3D();
 
-   GbTriFaceMesh3D* clone() { throw UbException(UB_EXARGS,"not implemented"); }
+   GbTriFaceMesh3D* clone();// { throw UbException(UB_EXARGS,"not implemented"); }
    void finalize() {}
 
    //void setRegardPointInPolyhedronTest(bool value) { this->regardPiO=value; }
@@ -260,6 +249,16 @@ public:
    //std::string getName();
    std::vector<Vertex>*  getNodes();
    std::vector<TriFace>* getTriangles();
+   
+   void setTransferViaFilename(bool transferViaFilename, std::string filename, double transX1, double transX2, double transX3)
+   {
+      this->filename = filename;
+      this->transferViaFilename = transferViaFilename;
+      this->transX1 = transX1;
+      this->transX2 = transX2;
+      this->transX3 = transX3;
+   }
+   void readMeshFromSTLFile(std::string filename, bool removeRedundantNodes);
 
    double getX1Minimum()  { if(!this->consistent) this->calculateValues(); return this->x1min;    }
    double getX1Maximum()  { if(!this->consistent) this->calculateValues(); return this->x1max;    }
@@ -274,7 +273,6 @@ public:
    double getX3Maximum()  { if(!this->consistent) this->calculateValues(); return this->x3max;    }
 
    void   calculateValues();
-   void   generateKdTree();
 
    double getVolume();
    void   deleteRedundantNodes();
@@ -282,13 +280,17 @@ public:
    UbTupleDouble6 calculateMomentOfInertia(double rhoP);
    UbTupleDouble3 calculateCenterOfGravity();
 
-   void transform(const double matrix[4][4]);
- 
-   void rotate(const double& alpha, const double& beta, const double& gamma);
+   void setCenterCoordinates(const double& x1, const double& x2, const double& x3);
+
+
    void scale(const double& sx1, const double& sx2, const double& sx3);
+   void rotate(const double& alpha, const double& beta, const double& gamma);
+   void rotateAroundPoint(const double& px1, const double& px2, const double& px3, const double& alpha, const double& beta, const double& gamma);
    void translate(const double& x1, const double& x2, const double& x3);
+   void reflectAcrossXYLine(const double& alpha);
 
    bool isPointInGbObject3D(const double& x1, const double& x2, const double& x3);
+   bool isPointInGbObject3D(const double& x1, const double& x2, const double& x3, int counter);
    bool isPointInGbObject3D(const double& x1, const double& x2, const double& x3, bool& pointIsOnBoundary);
 
    virtual GbLine3D* createClippedLine3D (GbPoint3D &point1,GbPoint3D &point2);
@@ -298,16 +300,7 @@ public:
 
    std::vector<GbTriFaceMesh3D::TriFace*> getTrianglesForVertex(Vertex* vertex);
 
-   void setKdTreeSplitAlgorithm(KDTREE_SPLITAGORITHM mode) 
-   { 
-      this->kdtreeSplitAlg = mode; 
-      bool rebuild = (mode != kdtreeSplitAlg);
-      if(   ( rebuild || !kdTree) 
-         && ( kdtreeSplitAlg == KDTREE_SHAPLIT || kdtreeSplitAlg == KDTREE_SPATIALSPLIT ) )
-      {
-         this->calculateValues();
-      }
-   }
+   void setKdTreeSplitAlgorithm(KDTREE_SPLITAGORITHM mode); 
    KDTREE_SPLITAGORITHM getKdTreeSplitAlgorithm() { return this->kdtreeSplitAlg; }
    Kd::Tree<double>* getKdTree() { return this->kdTree; }
 
@@ -317,20 +310,36 @@ public:
    void read(UbFileInput* in);  
 
    virtual UbTuple<std::string, std::string> writeMesh(std::string filename, WbWriter* writer, bool writeNormals=false, std::vector< std::string >* datanames=NULL, std::vector< std::vector < double > >* nodedata=NULL );
+   void writeMeshPly( const std::string& filename);
 
    /*======================================================================*/
    using GbObject3D::isPointInGbObject3D; //Grund: dadurch muss man hier  isPointInGbObject3D(GbPoint3D*) nicht ausprogrammieren, welche sonst hier "ueberdeckt" waere
 
-   bool intersectLine(const double& p1_x1, const double& p1_x2, const double& p1_x3, const double& p2_x1, const double& p2_x2, const double& p2_x3);
-
 #ifdef CAB_RCF
    template<class Archive>
    void SF_SERIALIZE(Archive & ar)
    {
       SF_SERIALIZE_PARENT<GbObject3D>(ar, *this);
       ar & kdtreeSplitAlg;
-      ar & nodes;
-      ar & triangles;
+      ar & transferViaFilename;
+      if(!transferViaFilename)
+      {
+         ar & nodes;
+         ar & triangles;
+      }
+      else
+      {
+         ar & filename;
+         ar & transX1;
+         ar & transX2;
+         ar & transX3;
+         if(ArchiveTools::isReading(ar) ) 
+         {
+            this->readMeshFromSTLFile(filename, true);
+            this->translate(transX1,transX2,transX3);
+         }
+      }
+      
       if(ArchiveTools::isReading(ar)) this->calculateValues();
    }
 #endif //CAB_RCF
@@ -341,6 +350,12 @@ protected:
 
    std::vector<Vertex>*  nodes;
    std::vector<TriFace>* triangles;
+   //for transfer
+   std::string filename;
+   bool transferViaFilename;
+   double transX1;
+   double transX2;
+   double transX3;
 
    double x1min;
    double x1max;
@@ -353,7 +368,6 @@ protected:
    double x3center;
 
    bool   consistent;
-   bool   kdTreeValid;
 
    bool buildVertTriRelationMap;
    std::multimap<Vertex*,TriFace*> relationVertTris;
diff --git a/src/VirtualFluidsBasics/numerics/geometry3d/creator/GbTriFaceMesh3DCreator.cpp b/src/VirtualFluidsBasics/numerics/geometry3d/creator/GbTriFaceMesh3DCreator.cpp
index 3d935050b3a38499284f997e411fb75162b9433e..a39bf633a30e5cd697e02409ff8638213397af61 100644
--- a/src/VirtualFluidsBasics/numerics/geometry3d/creator/GbTriFaceMesh3DCreator.cpp
+++ b/src/VirtualFluidsBasics/numerics/geometry3d/creator/GbTriFaceMesh3DCreator.cpp
@@ -20,6 +20,8 @@ GbTriFaceMesh3D* GbTriFaceMesh3DCreator::readMeshFromFile(string filename, strin
    //in "kleinbuchstaben" umwandeln
    transform(ext.begin(), ext.end(), ext.begin(), (int(*)(int))tolower); //(int(*)(int)) ist irgendso ein fieser cast, weil tolower ne alte c-methode ist
 
+   //UBLOG(logINFO, "GbTriFaceMesh3DCreator::readMeshFromFile - read " <<filename );
+
    if     ( !ext.compare("ply" ) ) return GbTriFaceMesh3DCreator::readMeshFromPLYFile(filename, meshName,splitAlg , removeRedundantNodes);
    else if( !ext.compare("stl" ) ) return GbTriFaceMesh3DCreator::readMeshFromSTLFile(filename, meshName,splitAlg , removeRedundantNodes);
    else if( !ext.compare("inp" ) ) return GbTriFaceMesh3DCreator::readMeshFromAVSFile(filename, meshName,splitAlg , removeRedundantNodes);
@@ -50,7 +52,7 @@ GbTriFaceMesh3D* GbTriFaceMesh3DCreator::readMeshFromMeshFile(UbFileInput* in, s
    }
    int numVertices = in->readInteger();
 
-   UBLOG(logINFO,"Number of vertices "<<numVertices);
+   UBLOG(logDEBUG1,"Number of vertices "<<numVertices);
 
    nodes->resize(numVertices);
    
@@ -63,7 +65,7 @@ GbTriFaceMesh3D* GbTriFaceMesh3DCreator::readMeshFromMeshFile(UbFileInput* in, s
       in->readLine();
       (*nodes)[i] = GbTriFaceMesh3D::Vertex(x,y,z);
    }
-   UBLOG(logINFO," - read vertices (#"<<numVertices<<") done");
+   UBLOG(logDEBUG1," - read vertices (#"<<numVertices<<") done");
 
    while( !in->eof() )
    {
@@ -73,7 +75,7 @@ GbTriFaceMesh3D* GbTriFaceMesh3DCreator::readMeshFromMeshFile(UbFileInput* in, s
    }
    int numFaces = in->readInteger();
    triangles->reserve(numFaces);
-   UBLOG(logINFO,"Number of faces    "<<numFaces);
+   UBLOG(logDEBUG1,"Number of faces    "<<numFaces);
 
    int j,k,l;
    for(int i=0; i<numFaces; i++)
@@ -85,7 +87,7 @@ GbTriFaceMesh3D* GbTriFaceMesh3DCreator::readMeshFromMeshFile(UbFileInput* in, s
 
       (*triangles).push_back(GbTriFaceMesh3D::TriFace(j,k,l));
    }
-   UBLOG(logINFO," - read faces (#"<<(int)triangles->size()<<", #nonTriangles="<<(int)triangles->size()-numFaces<<") done");
+   UBLOG(logDEBUG1," - read faces (#"<<(int)triangles->size()<<", #nonTriangles="<<(int)triangles->size()-numFaces<<") done");
 
    GbTriFaceMesh3D* mesh = new GbTriFaceMesh3D(meshName, nodes, triangles, splitAlg, removeRedundantNodes );
 
@@ -112,8 +114,8 @@ GbTriFaceMesh3D* GbTriFaceMesh3DCreator::readMeshFromPLYFile(UbFileInput* in, st
    int numFaces    = in->readIntegerAfterString("element face");
    in->setPosAfterLineWithString("end_header");
    
-   UBLOG(logINFO,"Number of vertices "<<numVertices);
-   UBLOG(logINFO,"Number of faces    "<<numFaces);
+   UBLOG(logDEBUG1,"Number of vertices "<<numVertices);
+   UBLOG(logDEBUG1,"Number of faces    "<<numFaces);
    
    nodes->resize(numVertices);
    triangles->reserve(numFaces);
@@ -129,7 +131,7 @@ GbTriFaceMesh3D* GbTriFaceMesh3DCreator::readMeshFromPLYFile(UbFileInput* in, st
       in->readLine();
       (*nodes)[i] = GbTriFaceMesh3D::Vertex(x,y,z);
    }
-   UBLOG(logINFO," - read vertices (#"<<numVertices<<") done");
+   UBLOG(logDEBUG1," - read vertices (#"<<numVertices<<") done");
 
    int p,j,k,l,n;
    onePercent = (int)UbMath::max(1,UbMath::integerRounding(numFaces*0.01));
@@ -176,7 +178,7 @@ GbTriFaceMesh3D* GbTriFaceMesh3DCreator::readMeshFromPLYFile(UbFileInput* in, st
       in->readLine();
 
    }
-   UBLOG(logINFO," - read faces (#"<<(int)triangles->size()<<", #nonTriangles="<<(int)triangles->size()-numFaces<<") done");
+   UBLOG(logDEBUG1," - read faces (#"<<(int)triangles->size()<<", #nonTriangles="<<(int)triangles->size()-numFaces<<") done");
 
    GbTriFaceMesh3D* mesh = new GbTriFaceMesh3D(meshName, nodes, triangles, splitAlg, removeRedundantNodes);
    
@@ -192,7 +194,7 @@ GbTriFaceMesh3D* GbTriFaceMesh3DCreator::readMeshFromSTLFile(string filename, st
 /*======================================================================*/
 GbTriFaceMesh3D* GbTriFaceMesh3DCreator::readMeshFromSTLFile(UbFileInput *in, string meshName, GbTriFaceMesh3D::KDTREE_SPLITAGORITHM splitAlg, bool removeRedundantNodes)
 {
-   UBLOG(logINFO,"GbTriFaceMesh3DCreator::readMeshFromSTLFile !!! Dieses Format hat leider redundante Knoten ...");
+   UBLOG(logDEBUG1,"GbTriFaceMesh3DCreator::readMeshFromSTLFile !!! Dieses Format hat leider redundante Knoten ...");
 
    vector<GbTriFaceMesh3D::Vertex>    *nodes     = new vector<GbTriFaceMesh3D::Vertex>;
    vector<GbTriFaceMesh3D::TriFace>   *triangles = new vector<GbTriFaceMesh3D::TriFace>;
@@ -230,119 +232,89 @@ GbTriFaceMesh3D* GbTriFaceMesh3DCreator::readMeshFromSTLFile(UbFileInput *in, st
       in->readLine();
       dummy = in->readString();
       nr+=3;
+      //std::cout<<"read mesh "<< nr <<" \n";
    }
 
    GbTriFaceMesh3D* mesh = new GbTriFaceMesh3D(meshName, nodes, triangles, splitAlg, removeRedundantNodes);
    
    return mesh;
 }
-// /*======================================================================*/
-// GbTriFaceMesh3D* GbTriFaceMesh3DCreator::readMeshFromMeshFile(string filename, string meshName, bool removeRedundantNodes)
-// {
-//    public static void read(String file, ArrayList<Node3d> nodeList, ArrayList<TrianglePatch> patches) throws FileReaderException {
-// 
-//       UBLOG(logINFO,"GbTriFaceMesh3DCreator::readMeshFromSTLFile !!! Dieses Format hat leider redundante Knoten ...");
-// 
-//    vector<GbTriFaceMesh3D::Vertex>    *nodes     = new vector<GbTriFaceMesh3D::Vertex>;
-//    vector<GbTriFaceMesh3D::TriFace>   *triangles = new vector<GbTriFaceMesh3D::TriFace>;
-//    string dummy;
-// 
-//    double x, y, z;
-//    int nr=0;
-// 
-//    in->readLine();
-//    while(dummy!="endsolid")
-//    {
-//       in->readLine();
-//       in->readLine();
-//       dummy = in->readString();
-//       if(dummy!="vertex") throw UbException(UB_EXARGS,"no vertex format");
-//       x=in->readDouble();
-//       y=in->readDouble();
-//       z=in->readDouble();
-//       nodes->push_back(GbTriFaceMesh3D::Vertex((float)x,(float)y,(float)z));
-//       in->readLine();
-//       in->readString();
-//       x=in->readDouble();
-//       y=in->readDouble();
-//       z=in->readDouble();
-//       nodes->push_back(GbTriFaceMesh3D::Vertex((float)x,(float)y,(float)z));
-//       in->readLine();
-//       in->readString();
-//       x=in->readDouble();
-//       y=in->readDouble();
-//       z=in->readDouble();
-//       nodes->push_back(GbTriFaceMesh3D::Vertex((float)x,(float)y,(float)z));
-//       triangles->push_back(GbTriFaceMesh3D::TriFace(nr,nr+1,nr+2));
-//       in->readLine();
-//       in->readLine();
-//       in->readLine();
-//       dummy = in->readString();
-//       nr+=3;
-//    }
-// 
-// 
-//    GbTriFaceMesh3D* mesh = new GbTriFaceMesh3D(meshName, nodes, triangles, splitAlg, removeRedundantNodes);
-// 
-//    return mesh;
-// 
-// 
-//    try {
-// 
-//       FileInput input = new FileInput(file);
-// 
-//       int line = 0;
-//       while(true)
-//       { 
-//          if(line>1000) break;            
-//          if(input.readLine().contains("Vertices")) 
-//             break;              
-//          line++;
-//       }
-// 
-//       int num_of_points = input.readInt();
-// 
-//       for (int i = 0; i < num_of_points; i++) {               
-//          float x = (float) input.readDouble();
-//          float y = (float) input.readDouble();
-//          float z = (float) input.readDouble();
-//          int nr = input.readInt();
-//          nodeList.add(new Node3d(x, y, z));
-//       }
-// 
-//       input.skipLine();
-//       input.skipLine();
-//       int num_of_triangles = input.readInt();
-// 
-//       for (int i = 0; i < num_of_triangles; i++) {
-// 
-//          int a = input.readInt();
-//          int b = input.readInt();
-//          int c = input.readInt();
-//          int nr = input.readInt();
-// 
-//          Node3d P1 = nodeList.get(a - 1);
-//          Node3d P2 = nodeList.get(b - 1);
-//          Node3d P3 = nodeList.get(c - 1);
-// 
-//          patches.add(new TrianglePatch(P1, P2, P3));
-//       }
-// 
-//       // END reading mesh file
-//    }
-// 
-//    -- 
-// 
-//       Dipl.-Ing. Sebastian Bindick
-// 
-//       Institute for Computational Modeling in Civil Engineering (iRMB) Technische Universität Braunschweig Pockelsstr. 3 (9th Floor) D-38106, Braunschweig, Germany
-// 
-//       phone +49 531/391-7598
-//       fax   +49 531/391-7599
-//       email    bindick@irmb.tu-bs.de
-//       web  www.irmb.tu-bs.de
-// 
-// 
+//////////////////////////////////////////////////////////////////////////
+GbTriFaceMesh3D* GbTriFaceMesh3DCreator::readMeshFromSTLFile2(string filename, string meshName, GbTriFaceMesh3D::KDTREE_SPLITAGORITHM splitAlg, bool removeRedundantNodes,  bool isBinaryFormat)
+{
+   vector<GbTriFaceMesh3D::Vertex>    *nodes     = new vector<GbTriFaceMesh3D::Vertex>;
+   vector<GbTriFaceMesh3D::TriFace>   *triangles = new vector<GbTriFaceMesh3D::TriFace>;
+   int nr=0;
+
+   if (!isBinaryFormat) {
+      ifstream in(filename.c_str());
+      if (!in.good()) 
+      {
+         delete nodes;
+         delete triangles;
+         UB_THROW(UbException(UB_EXARGS, "Can not open STL file: "+filename));
+      }
+      char title[80];
+      std::string s0, s1;
+      float n0, n1, n2, f0, f1, f2, f3, f4, f5, f6, f7, f8;
+      in.read(title, 80);
+      while (!in.eof()) {
+         in >> s0;                                // facet || endsolid
+         if (s0=="facet") {
+            in >> s1 >> n0 >> n1 >> n2;            // normal x y z
+            in >> s0 >> s1;                        // outer loop
+            in >> s0 >> f0 >> f1 >> f2;         // vertex x y z
+            in >> s0 >> f3 >> f4 >> f5;         // vertex x y z
+            in >> s0 >> f6 >> f7 >> f8;         // vertex x y z
+            in >> s0;                            // endloop
+            in >> s0;                            // endfacet
+            // Generate a new Triangle without Normal as 3 Vertices
+            nodes->push_back(GbTriFaceMesh3D::Vertex(f0, f1, f2));
+            nodes->push_back(GbTriFaceMesh3D::Vertex(f3, f4, f5));
+            nodes->push_back(GbTriFaceMesh3D::Vertex(f6, f7, f8));
+            triangles->push_back(GbTriFaceMesh3D::TriFace(nr,nr+1,nr+2));
+            nr+=3;
+         }
+         else if (s0=="endsolid") {
+            break;
+         }
+      }
+      in.close();
+   }
+   else {
+      FILE *f = fopen(filename.c_str(), "rb");
+      if (!f) 
+      {
+         delete nodes;
+         delete triangles;
+         UB_THROW(UbException(UB_EXARGS, "Can not open STL file: "+filename));
+      }
+      char title[80];
+      int nFaces;
+      fread(title, 80, 1, f);
+      fread((void*)&nFaces, 4, 1, f);
+      float v[12]; // normal=3, vertices=3*3 = 12
+      unsigned short uint16;
+      // Every Face is 50 Bytes: Normal(3*float), Vertices(9*float), 2 Bytes Spacer
+      for (size_t i=0; i<nFaces; ++i) {
+         for (size_t j=0; j<12; ++j) {
+            fread((void*)&v[j], sizeof(float), 1, f);
+         }
+         fread((void*)&uint16, sizeof(unsigned short), 1, f); // spacer between successive faces
+         nodes->push_back(GbTriFaceMesh3D::Vertex(v[3], v[4], v[5]));
+         nodes->push_back(GbTriFaceMesh3D::Vertex(v[6], v[7], v[8]));
+         nodes->push_back(GbTriFaceMesh3D::Vertex(v[9], v[10], v[11]));
+         triangles->push_back(GbTriFaceMesh3D::TriFace(nr, nr+1, nr+2));
+         nr+=3;
+      }
+      fclose(f);
+   }
+
+   GbTriFaceMesh3D* mesh = new GbTriFaceMesh3D(meshName, nodes, triangles, splitAlg, removeRedundantNodes);
+
+   return mesh;
+}
+
 /*======================================================================*/
 GbTriFaceMesh3D* GbTriFaceMesh3DCreator::readMeshFromAVSFile(string filename, string meshName, GbTriFaceMesh3D::KDTREE_SPLITAGORITHM splitAlg, bool removeRedundantNodes)
 {
@@ -353,7 +325,7 @@ GbTriFaceMesh3D* GbTriFaceMesh3DCreator::readMeshFromAVSFile(string filename, st
 /*======================================================================*/
 GbTriFaceMesh3D* GbTriFaceMesh3DCreator::readMeshFromAVSFile(UbFileInput *in, string meshName, GbTriFaceMesh3D::KDTREE_SPLITAGORITHM splitAlg , bool removeRedundantNodes)
 {
-   UBLOG(logINFO,"GbTriFaceMesh3DCreator.readMeshFromAVSFile !!! Dieses Format hat leider redundante Knoten ...");
+   UBLOG(logDEBUG1,"GbTriFaceMesh3DCreator.readMeshFromAVSFile !!! Dieses Format hat leider redundante Knoten ...");
 
    vector<GbTriFaceMesh3D::Vertex>    *nodes     = new vector<GbTriFaceMesh3D::Vertex>;
    vector<GbTriFaceMesh3D::TriFace>   *triangles = new vector<GbTriFaceMesh3D::TriFace>;
@@ -400,7 +372,7 @@ GbTriFaceMesh3D* GbTriFaceMesh3DCreator::readMeshFromVTKASCIIFile(string filenam
 /*======================================================================*/
 GbTriFaceMesh3D* GbTriFaceMesh3DCreator::readMeshFromVTKASCIIFile(UbFileInput *in, string meshName, GbTriFaceMesh3D::KDTREE_SPLITAGORITHM splitAlg, bool removeRedundantNodes)
 {
-   UBLOG(logINFO,"GbTriFaceMesh3DCreator.readMeshFromVTKASCIIFile !!! Dieses Format hat leider redundante Knoten ...");
+   UBLOG(logDEBUG1,"GbTriFaceMesh3DCreator.readMeshFromVTKASCIIFile !!! Dieses Format hat leider redundante Knoten ...");
 
    vector<GbTriFaceMesh3D::Vertex>    *nodes     = new vector<GbTriFaceMesh3D::Vertex>;
    vector<GbTriFaceMesh3D::TriFace>   *triangles = new vector<GbTriFaceMesh3D::TriFace>;
@@ -437,7 +409,7 @@ GbTriFaceMesh3D* GbTriFaceMesh3DCreator::readMeshFromVTKASCIIFile(UbFileInput *i
    in->readString();
    int numberTris  = in->readInteger();
    in->readLine();
-   UBLOG(logINFO,"numberTris:"<<numberTris);
+   UBLOG(logDEBUG1,"numberTris:"<<numberTris);
 
    int id1,id2,id3;
    for(int u=0;u<numberTris;u++)
@@ -449,10 +421,10 @@ GbTriFaceMesh3D* GbTriFaceMesh3DCreator::readMeshFromVTKASCIIFile(UbFileInput *i
       triangles->push_back(GbTriFaceMesh3D::TriFace(id1,id2,id3));
       //cout<<u<<" - id1,id2,id3:"<<id1<<","<<id2<<","<<id3<<endl;
    }
-   UBLOG(logINFO,"Tris gelesen");
+   UBLOG(logDEBUG1,"Tris gelesen");
 
    GbTriFaceMesh3D* mesh = new GbTriFaceMesh3D(meshName, nodes, triangles, splitAlg, removeRedundantNodes);
-   UBLOG(logINFO,"mesh erzeugt (with remove redundant nodes = "<< boolalpha <<removeRedundantNodes<<")");
+   UBLOG(logDEBUG1,"mesh erzeugt (with remove redundant nodes = "<< boolalpha <<removeRedundantNodes<<")");
 
 
    return mesh;
diff --git a/src/VirtualFluidsBasics/numerics/geometry3d/creator/GbTriFaceMesh3DCreator.h b/src/VirtualFluidsBasics/numerics/geometry3d/creator/GbTriFaceMesh3DCreator.h
index d2b57f69527c1d220bd5cc33cc0a31755e5bff8f..38247cdbe76c5a5ec487674151f19a7e869e064f 100644
--- a/src/VirtualFluidsBasics/numerics/geometry3d/creator/GbTriFaceMesh3DCreator.h
+++ b/src/VirtualFluidsBasics/numerics/geometry3d/creator/GbTriFaceMesh3DCreator.h
@@ -21,22 +21,23 @@ public:
       static GbTriFaceMesh3DCreator instance;
       return &instance;
    }
-   static GbTriFaceMesh3D* readMeshFromFile(std::string filename, std::string meshName, GbTriFaceMesh3D::KDTREE_SPLITAGORITHM splitAlg = GbTriFaceMesh3D::KDTREE_SHAPLIT, bool removeRedundantNodes=true);
+   static GbTriFaceMesh3D* readMeshFromFile(std::string filename, std::string meshName="", GbTriFaceMesh3D::KDTREE_SPLITAGORITHM splitAlg = GbTriFaceMesh3D::KDTREE_SAHPLIT, bool removeRedundantNodes=true);
 
-   static GbTriFaceMesh3D* readMeshFromMeshFile(std::string filename, std::string meshName, GbTriFaceMesh3D::KDTREE_SPLITAGORITHM splitAlg = GbTriFaceMesh3D::KDTREE_SHAPLIT, bool removeRedundantNodes=true);
-   static GbTriFaceMesh3D* readMeshFromMeshFile(UbFileInput* in, std::string meshName, GbTriFaceMesh3D::KDTREE_SPLITAGORITHM splitAlg = GbTriFaceMesh3D::KDTREE_SHAPLIT, bool removeRedundantNodes=true);
+   static GbTriFaceMesh3D* readMeshFromMeshFile(std::string filename, std::string meshName="", GbTriFaceMesh3D::KDTREE_SPLITAGORITHM splitAlg = GbTriFaceMesh3D::KDTREE_SAHPLIT, bool removeRedundantNodes=true);
+   static GbTriFaceMesh3D* readMeshFromMeshFile(UbFileInput* in, std::string meshName="", GbTriFaceMesh3D::KDTREE_SPLITAGORITHM splitAlg = GbTriFaceMesh3D::KDTREE_SAHPLIT, bool removeRedundantNodes=true);
 
-   static GbTriFaceMesh3D* readMeshFromPLYFile(std::string filename, std::string meshName, GbTriFaceMesh3D::KDTREE_SPLITAGORITHM splitAlg = GbTriFaceMesh3D::KDTREE_SHAPLIT, bool removeRedundantNodes=true);
-   static GbTriFaceMesh3D* readMeshFromPLYFile(UbFileInput* in, std::string meshName, GbTriFaceMesh3D::KDTREE_SPLITAGORITHM splitAlg = GbTriFaceMesh3D::KDTREE_SHAPLIT, bool removeRedundantNodes=true);
+   static GbTriFaceMesh3D* readMeshFromPLYFile(std::string filename, std::string meshName="", GbTriFaceMesh3D::KDTREE_SPLITAGORITHM splitAlg = GbTriFaceMesh3D::KDTREE_SAHPLIT, bool removeRedundantNodes=true);
+   static GbTriFaceMesh3D* readMeshFromPLYFile(UbFileInput* in, std::string meshName="", GbTriFaceMesh3D::KDTREE_SPLITAGORITHM splitAlg = GbTriFaceMesh3D::KDTREE_SAHPLIT, bool removeRedundantNodes=true);
 
-   static GbTriFaceMesh3D* readMeshFromSTLFile(std::string filename, std::string meshName, GbTriFaceMesh3D::KDTREE_SPLITAGORITHM splitAlg = GbTriFaceMesh3D::KDTREE_SHAPLIT, bool removeRedundantNodes=true); 
-   static GbTriFaceMesh3D* readMeshFromSTLFile(UbFileInput* in, std::string meshName, GbTriFaceMesh3D::KDTREE_SPLITAGORITHM splitAlg = GbTriFaceMesh3D::KDTREE_SHAPLIT, bool removeRedundantNodes=true);
+   static GbTriFaceMesh3D* readMeshFromSTLFile(std::string filename, std::string meshName="", GbTriFaceMesh3D::KDTREE_SPLITAGORITHM splitAlg = GbTriFaceMesh3D::KDTREE_SAHPLIT, bool removeRedundantNodes=true); 
+   static GbTriFaceMesh3D* readMeshFromSTLFile(UbFileInput* in, std::string meshName="", GbTriFaceMesh3D::KDTREE_SPLITAGORITHM splitAlg = GbTriFaceMesh3D::KDTREE_SAHPLIT, bool removeRedundantNodes=true);
+   static GbTriFaceMesh3D* readMeshFromSTLFile2(std::string filename, std::string meshName="", GbTriFaceMesh3D::KDTREE_SPLITAGORITHM splitAlg = GbTriFaceMesh3D::KDTREE_SAHPLIT, bool removeRedundantNodes=true,  bool isBinaryFormat=true);
 
-   static GbTriFaceMesh3D* readMeshFromAVSFile(std::string filename, std::string meshName, GbTriFaceMesh3D::KDTREE_SPLITAGORITHM splitAlg = GbTriFaceMesh3D::KDTREE_SHAPLIT, bool removeRedundantNodes=true); 
-   static GbTriFaceMesh3D* readMeshFromAVSFile(UbFileInput* in, std::string meshName, GbTriFaceMesh3D::KDTREE_SPLITAGORITHM splitAlg = GbTriFaceMesh3D::KDTREE_SHAPLIT, bool removeRedundantNodes=true);
+   static GbTriFaceMesh3D* readMeshFromAVSFile(std::string filename, std::string meshName="", GbTriFaceMesh3D::KDTREE_SPLITAGORITHM splitAlg = GbTriFaceMesh3D::KDTREE_SAHPLIT, bool removeRedundantNodes=true); 
+   static GbTriFaceMesh3D* readMeshFromAVSFile(UbFileInput* in, std::string meshName="", GbTriFaceMesh3D::KDTREE_SPLITAGORITHM splitAlg = GbTriFaceMesh3D::KDTREE_SAHPLIT, bool removeRedundantNodes=true);
 
-   static GbTriFaceMesh3D* readMeshFromVTKASCIIFile(std::string filename, std::string meshName, GbTriFaceMesh3D::KDTREE_SPLITAGORITHM splitAlg = GbTriFaceMesh3D::KDTREE_SHAPLIT, bool removeRedundantNodes=true); 
-   static GbTriFaceMesh3D* readMeshFromVTKASCIIFile(UbFileInput* in, std::string meshName, GbTriFaceMesh3D::KDTREE_SPLITAGORITHM splitAlg = GbTriFaceMesh3D::KDTREE_SHAPLIT, bool removeRedundantNodes=true);
+   static GbTriFaceMesh3D* readMeshFromVTKASCIIFile(std::string filename, std::string meshName="", GbTriFaceMesh3D::KDTREE_SPLITAGORITHM splitAlg = GbTriFaceMesh3D::KDTREE_SAHPLIT, bool removeRedundantNodes=true); 
+   static GbTriFaceMesh3D* readMeshFromVTKASCIIFile(UbFileInput* in, std::string meshName="", GbTriFaceMesh3D::KDTREE_SPLITAGORITHM splitAlg = GbTriFaceMesh3D::KDTREE_SAHPLIT, bool removeRedundantNodes=true);
 
    GbTriFaceMesh3D* createGbObject3D() { return new GbTriFaceMesh3D(); }
    
diff --git a/src/VirtualFluidsBasics/utilities/logger/implementations/LoggerImp.cpp b/src/VirtualFluidsBasics/utilities/logger/implementations/LoggerImp.cpp
index 2cb96eda4f040016e5975820e7b4e2ddf1c7ab35..c5ffd9908540214876be2ba0c3da162ca688168e 100644
--- a/src/VirtualFluidsBasics/utilities/logger/implementations/LoggerImp.cpp
+++ b/src/VirtualFluidsBasics/utilities/logger/implementations/LoggerImp.cpp
@@ -10,9 +10,9 @@ logging::LoggerImp::LoggerImp(std::ostream* stream) : logging::Logger(stream)
 {
     levelString[Level::WARNING] = "[WARNING]";
     levelString[Level::ERROR] = "[ERROR]";
-    levelString[Level::INFO_LOW] = "[LOW]";
-    levelString[Level::INFO_INTERMEDIATE] = "[INTERMEDIATE]";
-    levelString[Level::INFO_HIGH] = "[HIGH]";
+    levelString[Level::INFO_LOW] = "[INFO_LOW]";
+    levelString[Level::INFO_INTERMEDIATE] = "[INFO_INTERMEDIATE]";
+    levelString[Level::INFO_HIGH] = "[INFO_HIGH]";
 }
 
 logging::LoggerImp::~LoggerImp()
diff --git a/targets/apps/HULC/main.cpp b/targets/apps/HULC/main.cpp
index 36e0f3328ce7d690d9d361c8a0d5384ebaf536ba..a0036ef21e887c7a155850bff0d0c28e36767f76 100644
--- a/targets/apps/HULC/main.cpp
+++ b/targets/apps/HULC/main.cpp
@@ -249,7 +249,7 @@ void multipleLevel(const std::string& configPath)
     auto gridFactory = SPtr<GridFactory>(new GridFactory());
     gridFactory->setGridStrategy(SPtr<GridStrategy>(new GridCpuStrategy()));
     gridFactory->setGrid("grid");
-    gridFactory->setTriangularMeshDiscretizationMethod(TriangularMeshDiscretizationMethod::RAYCASTING);
+    gridFactory->setTriangularMeshDiscretizationMethod(TriangularMeshDiscretizationMethod::POINT_IN_OBJECT);
 
     //auto gridBuilderlevel = LevelGridBuilder::makeShared(Device::CPU, "D3Q27");
     auto gridBuilder = MultipleGridBuilder::makeShared(gridFactory);