| |
|
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| |
|
| |
|
| | #include <algorithm>
|
| |
|
| | #include <BRepMesh_IncrementalMesh.hxx>
|
| | #include <BRepTools.hxx>
|
| | #include <Standard_Version.hxx>
|
| | #include <TopoDS_Shape.hxx>
|
| |
|
| | #include <Base/Console.h>
|
| | #include <Base/Tools.h>
|
| | #include <Mod/Mesh/App/Mesh.h>
|
| | #include <Mod/Part/App/BRepMesh.h>
|
| | #include <Mod/Part/App/TopoShape.h>
|
| |
|
| | #include "Mesher.h"
|
| |
|
| | #ifdef HAVE_SMESH
|
| | # if defined(__clang__)
|
| | # pragma clang diagnostic push
|
| | # pragma clang diagnostic ignored "-Woverloaded-virtual"
|
| | # pragma clang diagnostic ignored "-Wextra-semi"
|
| | # elif defined(__GNUC__)
|
| | # pragma GCC diagnostic push
|
| | # pragma GCC diagnostic ignored "-Wpedantic"
|
| | # endif
|
| |
|
| | # include <SMESHDS_Mesh.hxx>
|
| | # include <SMESH_Gen.hxx>
|
| | # include <SMESH_Mesh.hxx>
|
| | # include <StdMeshers_MaxLength.hxx>
|
| |
|
| | # include <StdMeshers_Arithmetic1D.hxx>
|
| | # include <StdMeshers_AutomaticLength.hxx>
|
| | # include <StdMeshers_Deflection1D.hxx>
|
| | # include <StdMeshers_LocalLength.hxx>
|
| | # if SMESH_VERSION_MAJOR <= 9 && SMESH_VERSION_MINOR < 10
|
| | # include <StdMeshers_MEFISTO_2D.hxx>
|
| | # endif
|
| | # include <StdMeshers_MaxElementArea.hxx>
|
| | # include <StdMeshers_NumberOfSegments.hxx>
|
| | # include <StdMeshers_QuadranglePreference.hxx>
|
| | # include <StdMeshers_Quadrangle_2D.hxx>
|
| | # include <StdMeshers_Regular_1D.hxx>
|
| |
|
| | # include <StdMeshers_LengthFromEdges.hxx>
|
| | # include <StdMeshers_NotConformAllowed.hxx>
|
| | # if defined(HAVE_NETGEN)
|
| | # include <NETGENPlugin_Hypothesis_2D.hxx>
|
| | # include <NETGENPlugin_NETGEN_2D.hxx>
|
| | # include <NETGENPlugin_SimpleHypothesis_2D.hxx>
|
| | # endif
|
| | # if defined(__clang__)
|
| | # pragma clang diagnostic pop
|
| | # elif defined(__GNUC__)
|
| | # pragma GCC diagnostic pop
|
| | # endif
|
| | #endif
|
| |
|
| | using namespace MeshPart;
|
| |
|
| | SMESH_Gen* Mesher::_mesh_gen = nullptr;
|
| |
|
| |
|
| | MeshingOutput::MeshingOutput()
|
| | {
|
| | buffer.reserve(80);
|
| | }
|
| |
|
| | int MeshingOutput::overflow(int c)
|
| | {
|
| | if (c != EOF) {
|
| | buffer.push_back((char)c);
|
| | }
|
| | return c;
|
| | }
|
| |
|
| | int MeshingOutput::sync()
|
| | {
|
| |
|
| | 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) {
|
| |
|
| | sub = buffer.substr(pos + 3, buffer.size() - pos - 4);
|
| | }
|
| | else {
|
| | sub = buffer;
|
| | }
|
| | Base::Console().error("%s", sub.c_str());
|
| | }
|
| | buffer.clear();
|
| | }
|
| | return 0;
|
| | }
|
| |
|
| |
|
| |
|
| | namespace MeshPart
|
| | {
|
| |
|
| | class BrepMesh
|
| | {
|
| | bool segments;
|
| | std::vector<uint32_t> colors;
|
| |
|
| | public:
|
| | BrepMesh(bool s, const std::vector<uint32_t>& c)
|
| | : segments(s)
|
| | , colors(c)
|
| | {}
|
| |
|
| | Mesh::MeshObject* create(const std::vector<Part::TopoShape::Domain>& domains) const
|
| | {
|
| | std::vector<Base::Vector3d> points;
|
| | std::vector<Part::TopoShape::Facet> facets;
|
| | Part::BRepMesh mesh;
|
| | mesh.getFacesFromDomains(domains, points, facets);
|
| |
|
| | MeshCore::MeshFacetArray faces;
|
| | faces.reserve(facets.size());
|
| | std::transform(
|
| | facets.cbegin(),
|
| | facets.cend(),
|
| | std::back_inserter(faces),
|
| | [](const Part::TopoShape::Facet& face) {
|
| | return MeshCore::MeshFacet(face.I1, face.I2, face.I3);
|
| | }
|
| | );
|
| |
|
| | MeshCore::MeshPointArray verts;
|
| | verts.reserve(points.size());
|
| | for (const auto& it : points) {
|
| | verts.emplace_back(float(it.x), float(it.y), float(it.z));
|
| | }
|
| |
|
| | MeshCore::MeshKernel kernel;
|
| | kernel.Adopt(verts, faces, true);
|
| |
|
| |
|
| | std::vector<std::vector<MeshCore::FacetIndex>> meshSegments;
|
| |
|
| | std::map<uint32_t, std::vector<std::size_t>> colorMap;
|
| | for (std::size_t i = 0; i < colors.size(); i++) {
|
| | colorMap[colors[i]].push_back(i);
|
| | }
|
| |
|
| | bool createSegm = (colors.size() == domains.size());
|
| |
|
| |
|
| | if (createSegm || this->segments) {
|
| | auto segments = mesh.createSegments();
|
| | meshSegments.reserve(segments.size());
|
| | std::transform(
|
| | segments.cbegin(),
|
| | segments.cend(),
|
| | std::back_inserter(meshSegments),
|
| | [](const Part::BRepMesh::Segment& segm) {
|
| | std::vector<MeshCore::FacetIndex> faces;
|
| | faces.insert(faces.end(), segm.cbegin(), segm.cend());
|
| | return faces;
|
| | }
|
| | );
|
| | }
|
| |
|
| | Mesh::MeshObject* meshdata = new Mesh::MeshObject();
|
| | meshdata->swap(kernel);
|
| | if (createSegm) {
|
| | int index = 0;
|
| | for (const auto& it : colorMap) {
|
| | Mesh::Segment segm(meshdata, false);
|
| | for (auto jt : it.second) {
|
| | segm.addIndices(meshSegments[jt]);
|
| | }
|
| | segm.save(true);
|
| | std::stringstream str;
|
| | str << "patch" << index++;
|
| | segm.setName(str.str());
|
| | Base::Color col;
|
| | col.setPackedValue(it.first);
|
| | segm.setColor(col.asHexString());
|
| | meshdata->addSegment(segm);
|
| | }
|
| | }
|
| | else {
|
| | for (const auto& it : meshSegments) {
|
| | meshdata->addSegment(it);
|
| | }
|
| | }
|
| | return meshdata;
|
| | }
|
| | };
|
| | }
|
| |
|
| |
|
| |
|
| | Mesher::Mesher(const TopoDS_Shape& s)
|
| | : shape(s)
|
| | {}
|
| |
|
| | Mesher::~Mesher() = default;
|
| |
|
| | Mesh::MeshObject* Mesher::createStandard() const
|
| | {
|
| | if (!shape.IsNull()) {
|
| | BRepTools::Clean(shape);
|
| | BRepMesh_IncrementalMesh aMesh(shape, deflection, relative, angularDeflection);
|
| | }
|
| |
|
| | std::vector<Part::TopoShape::Domain> domains;
|
| | Part::TopoShape(shape).getDomains(domains);
|
| |
|
| | BrepMesh brepmesh(this->segments, this->colors);
|
| | return brepmesh.create(domains);
|
| | }
|
| |
|
| | Mesh::MeshObject* Mesher::createMesh() const
|
| | {
|
| |
|
| | if (method == Standard) {
|
| | return createStandard();
|
| | }
|
| |
|
| | #ifndef HAVE_SMESH
|
| | throw Base::RuntimeError("SMESH is not available on this platform");
|
| | #else
|
| | std::list<SMESH_Hypothesis*> hypoth;
|
| |
|
| | if (!Mesher::_mesh_gen) {
|
| | Mesher::_mesh_gen = new SMESH_Gen();
|
| | }
|
| | SMESH_Gen* meshgen = Mesher::_mesh_gen;
|
| |
|
| | # if SMESH_VERSION_MAJOR >= 9
|
| | SMESH_Mesh* mesh = meshgen->CreateMesh(true);
|
| | # else
|
| | SMESH_Mesh* mesh = meshgen->CreateMesh(0, true);
|
| | # endif
|
| |
|
| | int hyp = 0;
|
| |
|
| | switch (method) {
|
| | # if defined(HAVE_NETGEN)
|
| | case Netgen: {
|
| | # if SMESH_VERSION_MAJOR >= 9
|
| | NETGENPlugin_Hypothesis_2D* hyp2d = new NETGENPlugin_Hypothesis_2D(hyp++, meshgen);
|
| | # else
|
| | NETGENPlugin_Hypothesis_2D* hyp2d = new NETGENPlugin_Hypothesis_2D(hyp++, 0, meshgen);
|
| | # endif
|
| |
|
| | if (fineness >= 0 && fineness < 5) {
|
| | hyp2d->SetFineness(NETGENPlugin_Hypothesis_2D::Fineness(fineness));
|
| | }
|
| |
|
| | else {
|
| | if (growthRate > 0) {
|
| | hyp2d->SetGrowthRate(growthRate);
|
| | }
|
| | if (nbSegPerEdge > 0) {
|
| | hyp2d->SetNbSegPerEdge(nbSegPerEdge);
|
| | }
|
| | if (nbSegPerRadius > 0) {
|
| | hyp2d->SetNbSegPerRadius(nbSegPerRadius);
|
| | }
|
| | }
|
| |
|
| | if (maxLen > 0) {
|
| | hyp2d->SetMaxSize(maxLen);
|
| | }
|
| | if (minLen > 0) {
|
| | hyp2d->SetMinSize(minLen);
|
| | }
|
| |
|
| | hyp2d->SetQuadAllowed(allowquad);
|
| | hyp2d->SetOptimize(optimize);
|
| | hyp2d->SetSecondOrder(secondOrder);
|
| | hypoth.push_back(hyp2d);
|
| |
|
| | # if SMESH_VERSION_MAJOR >= 9
|
| | NETGENPlugin_NETGEN_2D* alg2d = new NETGENPlugin_NETGEN_2D(hyp++, meshgen);
|
| | # else
|
| | NETGENPlugin_NETGEN_2D* alg2d = new NETGENPlugin_NETGEN_2D(hyp++, 0, meshgen);
|
| | # endif
|
| | hypoth.push_back(alg2d);
|
| | } break;
|
| | # endif
|
| | # if SMESH_VERSION_MAJOR <= 9 && SMESH_VERSION_MINOR < 10
|
| | # if defined(HAVE_MEFISTO)
|
| | case Mefisto: {
|
| | if (maxLength > 0) {
|
| | # if SMESH_VERSION_MAJOR >= 9
|
| | StdMeshers_MaxLength* hyp1d = new StdMeshers_MaxLength(hyp++, meshgen);
|
| | # else
|
| | StdMeshers_MaxLength* hyp1d = new StdMeshers_MaxLength(hyp++, 0, meshgen);
|
| | # endif
|
| | hyp1d->SetLength(maxLength);
|
| | hypoth.push_back(hyp1d);
|
| | }
|
| | else if (localLength > 0) {
|
| | # if SMESH_VERSION_MAJOR >= 9
|
| | StdMeshers_LocalLength* hyp1d = new StdMeshers_LocalLength(hyp++, meshgen);
|
| | # else
|
| | StdMeshers_LocalLength* hyp1d = new StdMeshers_LocalLength(hyp++, 0, meshgen);
|
| | # endif
|
| | hyp1d->SetLength(localLength);
|
| | hypoth.push_back(hyp1d);
|
| | }
|
| | else if (maxArea > 0) {
|
| | # if SMESH_VERSION_MAJOR >= 9
|
| | StdMeshers_MaxElementArea* hyp2d = new StdMeshers_MaxElementArea(hyp++, meshgen);
|
| | # else
|
| | StdMeshers_MaxElementArea* hyp2d = new StdMeshers_MaxElementArea(hyp++, 0, meshgen);
|
| | # endif
|
| | hyp2d->SetMaxArea(maxArea);
|
| | hypoth.push_back(hyp2d);
|
| | }
|
| | else if (deflection > 0) {
|
| | # if SMESH_VERSION_MAJOR >= 9
|
| | StdMeshers_Deflection1D* hyp1d = new StdMeshers_Deflection1D(hyp++, meshgen);
|
| | # else
|
| | StdMeshers_Deflection1D* hyp1d = new StdMeshers_Deflection1D(hyp++, 0, meshgen);
|
| | # endif
|
| | hyp1d->SetDeflection(deflection);
|
| | hypoth.push_back(hyp1d);
|
| | }
|
| | else if (minLen > 0 && maxLen > 0) {
|
| | # if SMESH_VERSION_MAJOR >= 9
|
| | StdMeshers_Arithmetic1D* hyp1d = new StdMeshers_Arithmetic1D(hyp++, meshgen);
|
| | # else
|
| | StdMeshers_Arithmetic1D* hyp1d = new StdMeshers_Arithmetic1D(hyp++, 0, meshgen);
|
| | # endif
|
| | hyp1d->SetLength(minLen, false);
|
| | hyp1d->SetLength(maxLen, true);
|
| | hypoth.push_back(hyp1d);
|
| | }
|
| | else {
|
| | # if SMESH_VERSION_MAJOR >= 9
|
| | StdMeshers_AutomaticLength* hyp1d = new StdMeshers_AutomaticLength(hyp++, meshgen);
|
| | # else
|
| | StdMeshers_AutomaticLength* hyp1d = new StdMeshers_AutomaticLength(hyp++, 0, meshgen);
|
| | # endif
|
| | hypoth.push_back(hyp1d);
|
| | }
|
| |
|
| | {
|
| | # if SMESH_VERSION_MAJOR >= 9
|
| | StdMeshers_NumberOfSegments* hyp1d = new StdMeshers_NumberOfSegments(hyp++, meshgen);
|
| | # else
|
| | StdMeshers_NumberOfSegments* hyp1d = new StdMeshers_NumberOfSegments(hyp++, 0, meshgen);
|
| | # endif
|
| | hyp1d->SetNumberOfSegments(1);
|
| | hypoth.push_back(hyp1d);
|
| | }
|
| |
|
| | if (regular) {
|
| | # if SMESH_VERSION_MAJOR >= 9
|
| | StdMeshers_Regular_1D* hyp1d = new StdMeshers_Regular_1D(hyp++, meshgen);
|
| | # else
|
| | StdMeshers_Regular_1D* hyp1d = new StdMeshers_Regular_1D(hyp++, 0, meshgen);
|
| | # endif
|
| | hypoth.push_back(hyp1d);
|
| | }
|
| |
|
| | # if SMESH_VERSION_MAJOR >= 9
|
| | StdMeshers_MEFISTO_2D* alg2d = new StdMeshers_MEFISTO_2D(hyp++, meshgen);
|
| | # else
|
| | StdMeshers_MEFISTO_2D* alg2d = new StdMeshers_MEFISTO_2D(hyp++, 0, meshgen);
|
| | # endif
|
| | hypoth.push_back(alg2d);
|
| | } break;
|
| | # endif
|
| | # endif
|
| | default:
|
| | break;
|
| | }
|
| |
|
| |
|
| | MeshingOutput stdcout;
|
| | std::streambuf* oldcout = std::cout.rdbuf(&stdcout);
|
| |
|
| |
|
| | mesh->ShapeToMesh(shape);
|
| | for (int i = 0; i < hyp; i++) {
|
| | mesh->AddHypothesis(shape, i);
|
| | }
|
| | meshgen->Compute(*mesh, mesh->GetShapeToMesh());
|
| |
|
| |
|
| | std::cout.rdbuf(oldcout);
|
| |
|
| |
|
| | Mesh::MeshObject* meshdata = createFrom(mesh);
|
| |
|
| |
|
| | TopoDS_Shape aNull;
|
| | mesh->ShapeToMesh(aNull);
|
| | mesh->Clear();
|
| | delete mesh;
|
| | for (auto it : hypoth) {
|
| | delete it;
|
| | }
|
| |
|
| | return meshdata;
|
| | #endif
|
| | }
|
| |
|
| | Mesh::MeshObject* Mesher::createFrom(SMESH_Mesh* mesh) const
|
| | {
|
| |
|
| | SMDS_FaceIteratorPtr aFaceIter = mesh->GetMeshDS()->facesIterator();
|
| | SMDS_NodeIteratorPtr aNodeIter = mesh->GetMeshDS()->nodesIterator();
|
| |
|
| | MeshCore::MeshPointArray verts;
|
| | MeshCore::MeshFacetArray faces;
|
| | verts.reserve(mesh->NbNodes());
|
| | faces.reserve(mesh->NbFaces());
|
| |
|
| | int index = 0;
|
| | std::map<const SMDS_MeshNode*, int> mapNodeIndex;
|
| | for (; aNodeIter->more();) {
|
| | const SMDS_MeshNode* aNode = aNodeIter->next();
|
| | MeshCore::MeshPoint p;
|
| | p.Set((float)aNode->X(), (float)aNode->Y(), (float)aNode->Z());
|
| | verts.push_back(p);
|
| | mapNodeIndex[aNode] = index++;
|
| | }
|
| |
|
| | for (; aFaceIter->more();) {
|
| | const SMDS_MeshFace* aFace = aFaceIter->next();
|
| | 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);
|
| |
|
| | 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);
|
| | }
|
| | else if (aFace->NbNodes() == 6) {
|
| | MeshCore::MeshFacet f1, f2, f3, f4;
|
| | 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);
|
| | const SMDS_MeshNode* node4 = aFace->GetNode(4);
|
| | const SMDS_MeshNode* node5 = aFace->GetNode(5);
|
| |
|
| | f1._aulPoints[0] = mapNodeIndex[node0];
|
| | f1._aulPoints[1] = mapNodeIndex[node3];
|
| | f1._aulPoints[2] = mapNodeIndex[node5];
|
| |
|
| | f2._aulPoints[0] = mapNodeIndex[node1];
|
| | f2._aulPoints[1] = mapNodeIndex[node4];
|
| | f2._aulPoints[2] = mapNodeIndex[node3];
|
| |
|
| | f3._aulPoints[0] = mapNodeIndex[node2];
|
| | f3._aulPoints[1] = mapNodeIndex[node5];
|
| | f3._aulPoints[2] = mapNodeIndex[node4];
|
| |
|
| | f4._aulPoints[0] = mapNodeIndex[node3];
|
| | f4._aulPoints[1] = mapNodeIndex[node4];
|
| | f4._aulPoints[2] = mapNodeIndex[node5];
|
| |
|
| | faces.push_back(f1);
|
| | faces.push_back(f2);
|
| | faces.push_back(f3);
|
| | faces.push_back(f4);
|
| | }
|
| | else if (aFace->NbNodes() == 8) {
|
| | MeshCore::MeshFacet f1, f2, f3, f4, f5, f6;
|
| | 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);
|
| | const SMDS_MeshNode* node4 = aFace->GetNode(4);
|
| | const SMDS_MeshNode* node5 = aFace->GetNode(5);
|
| | const SMDS_MeshNode* node6 = aFace->GetNode(6);
|
| | const SMDS_MeshNode* node7 = aFace->GetNode(7);
|
| |
|
| | f1._aulPoints[0] = mapNodeIndex[node0];
|
| | f1._aulPoints[1] = mapNodeIndex[node4];
|
| | f1._aulPoints[2] = mapNodeIndex[node7];
|
| |
|
| | f2._aulPoints[0] = mapNodeIndex[node1];
|
| | f2._aulPoints[1] = mapNodeIndex[node5];
|
| | f2._aulPoints[2] = mapNodeIndex[node4];
|
| |
|
| | f3._aulPoints[0] = mapNodeIndex[node2];
|
| | f3._aulPoints[1] = mapNodeIndex[node6];
|
| | f3._aulPoints[2] = mapNodeIndex[node5];
|
| |
|
| | f4._aulPoints[0] = mapNodeIndex[node3];
|
| | f4._aulPoints[1] = mapNodeIndex[node7];
|
| | f4._aulPoints[2] = mapNodeIndex[node6];
|
| |
|
| |
|
| |
|
| | Base::Vector3d v4(node4->X(), node4->Y(), node4->Z());
|
| | Base::Vector3d v5(node5->X(), node5->Y(), node5->Z());
|
| | Base::Vector3d v6(node6->X(), node6->Y(), node6->Z());
|
| | Base::Vector3d v7(node7->X(), node7->Y(), node7->Z());
|
| | double dist46 = Base::DistanceP2(v4, v6);
|
| | double dist57 = Base::DistanceP2(v5, v7);
|
| | if (dist46 > dist57) {
|
| | f5._aulPoints[0] = mapNodeIndex[node4];
|
| | f5._aulPoints[1] = mapNodeIndex[node6];
|
| | f5._aulPoints[2] = mapNodeIndex[node7];
|
| |
|
| | f6._aulPoints[0] = mapNodeIndex[node4];
|
| | f6._aulPoints[1] = mapNodeIndex[node5];
|
| | f6._aulPoints[2] = mapNodeIndex[node6];
|
| | }
|
| | else {
|
| | f5._aulPoints[0] = mapNodeIndex[node4];
|
| | f5._aulPoints[1] = mapNodeIndex[node5];
|
| | f5._aulPoints[2] = mapNodeIndex[node7];
|
| |
|
| | f6._aulPoints[0] = mapNodeIndex[node5];
|
| | f6._aulPoints[1] = mapNodeIndex[node6];
|
| | f6._aulPoints[2] = mapNodeIndex[node7];
|
| | }
|
| |
|
| | faces.push_back(f1);
|
| | faces.push_back(f2);
|
| | faces.push_back(f3);
|
| | faces.push_back(f4);
|
| | faces.push_back(f5);
|
| | faces.push_back(f6);
|
| | }
|
| | else {
|
| | Base::Console().warning("Face with %d nodes ignored\n", aFace->NbNodes());
|
| | }
|
| | }
|
| |
|
| | MeshCore::MeshKernel kernel;
|
| | kernel.Adopt(verts, faces, true);
|
| |
|
| | Mesh::MeshObject* meshdata = new Mesh::MeshObject();
|
| | meshdata->swap(kernel);
|
| | return meshdata;
|
| | }
|
| |
|