From 774bf81bb8c1f3cee54056028348b2b61d6d91ba Mon Sep 17 00:00:00 2001 From: Soeren Peters <peters@irmb.tu-bs.de> Date: Mon, 14 May 2018 10:22:40 +0200 Subject: [PATCH] - broken stl discretization!! --- .gitignore | 1 + .../TriangularMesh/TriangularMeshStrategy.cpp | 256 +++++ .../TriangularMesh/TriangularMeshStrategy.h | 264 +---- .../grid/GridBuilder/MultipleGridBuilder.cpp | 3 + .../GridCpuStrategy/GridCpuStrategy.cpp | 2 - .../numerics/geometry3d/GbTriFaceMesh3D.cpp | 903 ++++++++++++++---- .../numerics/geometry3d/GbTriFaceMesh3D.h | 114 ++- .../creator/GbTriFaceMesh3DCreator.cpp | 214 ++--- .../creator/GbTriFaceMesh3DCreator.h | 23 +- .../logger/implementations/LoggerImp.cpp | 6 +- targets/apps/HULC/main.cpp | 2 +- 11 files changed, 1157 insertions(+), 631 deletions(-) create mode 100644 src/GridGenerator/geometries/TriangularMesh/TriangularMeshStrategy.cpp diff --git a/.gitignore b/.gitignore index d87980fd0..42b843b17 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 000000000..e5936122e --- /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 80dc7fa02..f4e70be94 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 8cf446aac..04a351dca 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 5f324e929..8d55383fa 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 10f3c07f4..0beb2b12b 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 470c31eee..96b18593c 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 3d935050b..a39bf633a 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 d2b57f695..38247cdbe 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 2cb96eda4..c5ffd9908 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 36e0f3328..a0036ef21 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); -- GitLab