diff --git a/src/Mod/MeshPart/App/CMakeLists.txt b/src/Mod/MeshPart/App/CMakeLists.txt index 64860eff0a45..08cdc91fe542 100644 --- a/src/Mod/MeshPart/App/CMakeLists.txt +++ b/src/Mod/MeshPart/App/CMakeLists.txt @@ -22,13 +22,22 @@ include_directories( link_directories(${OCC_LIBRARY_DIR}) -set(MeshPart_LIBS - Part - Mesh - StdMeshers - #NETGENPlugin - SMESH -) +if(FREECAD_BUILD_FEM_NETGEN) + set(MeshPart_LIBS + Part + Mesh + StdMeshers + NETGENPlugin + SMESH + ) +else(FREECAD_BUILD_FEM_NETGEN) + set(MeshPart_LIBS + Part + Mesh + StdMeshers + SMESH + ) +endif(FREECAD_BUILD_FEM_NETGEN) SET(MeshPart_SRCS diff --git a/src/Mod/MeshPart/App/Mesher.cpp b/src/Mod/MeshPart/App/Mesher.cpp index 82976d4c14f4..7b4be92c7ac0 100644 --- a/src/Mod/MeshPart/App/Mesher.cpp +++ b/src/Mod/MeshPart/App/Mesher.cpp @@ -23,6 +23,7 @@ #include "PreCompiled.h" #include "Mesher.h" +#include #include #include @@ -45,13 +46,51 @@ #include #include #include +#if defined(_MSC_VER) +#include +#include +#include +#endif #endif // HAVE_SMESH using namespace MeshPart; +MeshingOutput::MeshingOutput() +{ + buffer.reserve(80); +} + +int MeshingOutput::overflow(int c) +{ + if (c != EOF) + buffer.push_back((char)c); + return c; +} + +int MeshingOutput::sync() +{ + // Print as log as this might be verbose + if (!buffer.empty()) { + if (buffer.find("failed") != std::string::npos) { + std::string::size_type pos = buffer.find(" : "); + std::string sub; + if (pos != std::string::npos) { + // chop the last newline + sub = buffer.substr(pos+3, buffer.size()-pos-4); + } + else { + sub = buffer; + } + Base::Console().Error("%s", sub.c_str()); + } + buffer.clear(); + } + return 0; +} + Mesher::Mesher(const TopoDS_Shape& s) : shape(s), maxLength(0), maxArea(0), localLength(0), - regular(false) + deflection(0), regular(false) { } @@ -70,6 +109,60 @@ Mesh::MeshObject* Mesher::createMesh() const SMESH_Mesh* mesh = meshgen->CreateMesh(0, true); int hyp=0; +#if defined(_MSC_VER) +#if 0 + NETGENPlugin_SimpleHypothesis_2D* hyp2d = new NETGENPlugin_SimpleHypothesis_2D(hyp++,0,meshgen); + // localLength overrides maxLength if both are set + if (maxLength > 0) { + hyp2d->SetLocalLength(maxLength); + } + + if (localLength > 0) { + hyp2d->SetLocalLength(localLength); + } + + if (maxArea > 0) { + hyp2d->SetMaxElementArea(maxArea); + } + + hyp2d->SetNumberOfSegments(1); + hypoth.push_back(hyp2d); +#else + NETGENPlugin_Hypothesis_2D* hyp2d = new NETGENPlugin_Hypothesis_2D(hyp++,0,meshgen); + + float growth = 0; + if (maxLength > 0 && localLength > 0) { + growth = std::min(maxLength, localLength); + } + else if (maxLength > 0) { + growth = maxLength; + } + else if (localLength > 0) { + growth = localLength; + } + + if (growth == 0.0) + hyp2d->SetFineness(NETGENPlugin_Hypothesis_2D::Moderate); + else if (growth <= 0.1) + hyp2d->SetFineness(NETGENPlugin_Hypothesis_2D::VeryFine); + else if (growth <= 0.2f) + hyp2d->SetFineness(NETGENPlugin_Hypothesis_2D::Fine); + else if (growth <= 0.5f) + hyp2d->SetFineness(NETGENPlugin_Hypothesis_2D::Moderate); + else if (growth <= 0.7f) + hyp2d->SetFineness(NETGENPlugin_Hypothesis_2D::Coarse); + else + hyp2d->SetFineness(NETGENPlugin_Hypothesis_2D::VeryCoarse); + + hyp2d->SetGrowthRate(growth); + hyp2d->SetQuadAllowed(true); + hyp2d->SetOptimize(true); + hypoth.push_back(hyp2d); +#endif + + NETGENPlugin_NETGEN_2D* alg2d = new NETGENPlugin_NETGEN_2D(hyp++,0,meshgen); + hypoth.push_back(alg2d); +#else if (maxLength > 0) { StdMeshers_MaxLength* hyp1d = new StdMeshers_MaxLength(hyp++, 0, meshgen); hyp1d->SetLength(maxLength); @@ -111,22 +204,25 @@ Mesh::MeshObject* Mesher::createMesh() const hypoth.push_back(hyp1d); } -#if 1 StdMeshers_TrianglePreference* hyp2d_1 = new StdMeshers_TrianglePreference(hyp++,0,meshgen); hypoth.push_back(hyp2d_1); StdMeshers_MEFISTO_2D* alg2d = new StdMeshers_MEFISTO_2D(hyp++,0,meshgen); hypoth.push_back(alg2d); -#else - StdMeshers_QuadranglePreference hyp2d_1(hyp++,0,meshgen); - StdMeshers_Quadrangle_2D alg2d(hyp++,0,meshgen); #endif + // Set new cout + MeshingOutput stdcout; + std::streambuf* oldcout = std::cout.rdbuf(&stdcout); + // Apply the hypothesis and create the mesh mesh->ShapeToMesh(shape); for (int i=0; iAddHypothesis(shape, i); meshgen->Compute(*mesh, mesh->GetShapeToMesh()); + // Restore old cout + std::cout.rdbuf(oldcout); + // build up the mesh structure SMDS_FaceIteratorPtr aFaceIter = mesh->GetMeshDS()->facesIterator(); SMDS_NodeIteratorPtr aNodeIter = mesh->GetMeshDS()->nodesIterator(); @@ -147,21 +243,37 @@ Mesh::MeshObject* Mesher::createMesh() const } for (;aFaceIter->more();) { const SMDS_MeshFace* aFace = aFaceIter->next(); - MeshCore::MeshFacet f; - for (int i=0; i<3;i++) { - const SMDS_MeshNode* node = aFace->GetNode(i); - //int index = node->GetID() - 1; - f._aulPoints[i] = /*index*/mapNodeIndex[node]; + if (aFace->NbNodes() == 3) { + MeshCore::MeshFacet f; + for (int i=0; i<3;i++) { + const SMDS_MeshNode* node = aFace->GetNode(i); + f._aulPoints[i] = mapNodeIndex[node]; + } + faces.push_back(f); } + else if (aFace->NbNodes() == 4) { + MeshCore::MeshFacet f1, f2; + const SMDS_MeshNode* node0 = aFace->GetNode(0); + const SMDS_MeshNode* node1 = aFace->GetNode(1); + const SMDS_MeshNode* node2 = aFace->GetNode(2); + const SMDS_MeshNode* node3 = aFace->GetNode(3); - faces.push_back(f); + f1._aulPoints[0] = mapNodeIndex[node0]; + f1._aulPoints[1] = mapNodeIndex[node1]; + f1._aulPoints[2] = mapNodeIndex[node2]; + + f2._aulPoints[0] = mapNodeIndex[node0]; + f2._aulPoints[1] = mapNodeIndex[node2]; + f2._aulPoints[2] = mapNodeIndex[node3]; + + faces.push_back(f1); + faces.push_back(f2); + } } // clean up - //FIXME: Why can't we delete this object? -#if defined(__GNUC__) - delete meshgen; // crashes with MSVC -#endif + delete meshgen; + TopoDS_Shape aNull; mesh->ShapeToMesh(aNull); mesh->Clear(); diff --git a/src/Mod/MeshPart/App/Mesher.h b/src/Mod/MeshPart/App/Mesher.h index 1d892694d589..3839273e42f1 100644 --- a/src/Mod/MeshPart/App/Mesher.h +++ b/src/Mod/MeshPart/App/Mesher.h @@ -23,6 +23,8 @@ #ifndef MESHPART_MESHER_H #define MESHPART_MESHER_H +#include + class TopoDS_Shape; namespace Mesh { class MeshObject; } @@ -66,6 +68,19 @@ class Mesher bool regular; }; +class MeshingOutput : public std::streambuf +{ +public: + MeshingOutput(); + +protected: + int overflow(int c = EOF); + int sync(); + +private: + std::string buffer; +}; + } // namespace MeshPart #endif // MESHPART_MESHER_H diff --git a/src/Mod/MeshPart/Gui/Tessellation.cpp b/src/Mod/MeshPart/Gui/Tessellation.cpp index 5e7924bf61d4..5b1094a7eadb 100644 --- a/src/Mod/MeshPart/Gui/Tessellation.cpp +++ b/src/Mod/MeshPart/Gui/Tessellation.cpp @@ -185,6 +185,7 @@ bool Tessellation::accept() "__mesh__=__doc__.addObject(\"Mesh::Feature\",\"Mesh\")\n" "__mesh__.Mesh=MeshPart.meshFromShape(__doc__.getObject(\"%2\").Shape,%3,0,0,%4)\n" "__mesh__.Label=\"%5 (Meshed)\"\n" + "__mesh__.ViewObject.CreaseAngle=25.0\n" "del __doc__, __mesh__\n") .arg(this->document) .arg(shape)