Пример #1
0
Py::Tuple FemMeshPy::getFaces(void) const
{
    std::set<int> ids;
    SMDS_FaceIteratorPtr aFaceIter = getFemMeshPtr()->getSMesh()->GetMeshDS()->facesIterator();
    while (aFaceIter->more()) {
        const SMDS_MeshFace* aFace = aFaceIter->next();
        ids.insert(aFace->GetID());
    }

    Py::Tuple tuple(ids.size());
    int index = 0;
    for (std::set<int>::iterator it = ids.begin(); it != ids.end(); ++it) {
        tuple.setItem(index++, Py::Long(*it));
    }

    return tuple;
}
Пример #2
0
bool NETGENPlugin_NETGEN_3D::Compute(SMESH_Mesh& aMesh,
                                     SMESH_MesherHelper* aHelper)
{
    MESSAGE("NETGENPlugin_NETGEN_3D::Compute with maxElmentsize = " << _maxElementVolume);
    const int invalid_ID = -1;
    bool _quadraticMesh = false;
    typedef map< const SMDS_MeshNode*, int, TIDCompare > TNodeToIDMap;
    TNodeToIDMap nodeToNetgenID;
    list< const SMDS_MeshElement* > triangles;
    SMESHDS_Mesh* MeshDS = aHelper->GetMeshDS();

    SMESH_MesherHelper::MType MeshType = aHelper->IsQuadraticMesh();

    if(MeshType == SMESH_MesherHelper::COMP)
        return error( COMPERR_BAD_INPUT_MESH,
                      SMESH_Comment("Mesh with linear and quadratic elements given."));
    else if (MeshType == SMESH_MesherHelper::QUADRATIC)
        _quadraticMesh = true;

    StdMeshers_QuadToTriaAdaptor Adaptor;
    Adaptor.Compute(aMesh);

    SMDS_FaceIteratorPtr fIt = MeshDS->facesIterator();
    TIDSortedElemSet sortedFaces; //  0020279: control the "random" use when using mesh algorithms
    while( fIt->more()) sortedFaces.insert( fIt->next() );

    TIDSortedElemSet::iterator itFace = sortedFaces.begin(), fEnd = sortedFaces.end();
    for ( ; itFace != fEnd; ++itFace ) {
        // check element
        const SMDS_MeshElement* elem = *itFace;
        if ( !elem )
            return error( COMPERR_BAD_INPUT_MESH, "Null element encounters");
        bool isTraingle = ( elem->NbNodes()==3 || (_quadraticMesh && elem->NbNodes()==6 ));
        if ( !isTraingle ) {
            //return error( COMPERR_BAD_INPUT_MESH,
            //              SMESH_Comment("Not triangle element ")<<elem->GetID());
            // using adaptor
            const list<const SMDS_FaceOfNodes*>* faces = Adaptor.GetTriangles(elem);
            if(faces==0) {
                return error( COMPERR_BAD_INPUT_MESH,
                              SMESH_Comment("Not triangles in adaptor for element ")<<elem->GetID());
            }
            list<const SMDS_FaceOfNodes*>::const_iterator itf = faces->begin();
            for(; itf!=faces->end(); itf++ ) {
                triangles.push_back( (*itf) );
                // put triange's nodes to nodeToNetgenID map
                SMDS_ElemIteratorPtr triangleNodesIt = (*itf)->nodesIterator();
                while ( triangleNodesIt->more() ) {
                    const SMDS_MeshNode * node =
                        static_cast<const SMDS_MeshNode *>(triangleNodesIt->next());
                    if(aHelper->IsMedium(node))
                        continue;
                    nodeToNetgenID.insert( make_pair( node, invalid_ID ));
                }
            }
        }
        else {
            // keep a triangle
            triangles.push_back( elem );
            // put elem nodes to nodeToNetgenID map
            SMDS_ElemIteratorPtr triangleNodesIt = elem->nodesIterator();
            while ( triangleNodesIt->more() ) {
                const SMDS_MeshNode * node =
                    static_cast<const SMDS_MeshNode *>(triangleNodesIt->next());
                if(aHelper->IsMedium(node))
                    continue;
                nodeToNetgenID.insert( make_pair( node, invalid_ID ));
            }
        }
    }

    // ---------------------------------
    // Feed the Netgen with surface mesh
    // ---------------------------------

    int Netgen_NbOfNodes = 0;
    int Netgen_param2ndOrder = 0;
    double Netgen_paramFine = 1.;
    double Netgen_paramSize = pow( 72, 1/6. ) * pow( _maxElementVolume, 1/3. );

    double Netgen_point[3];
    int Netgen_triangle[3];
    int Netgen_tetrahedron[4];

    Ng_Init();

    Ng_Mesh * Netgen_mesh = Ng_NewMesh();

    // set nodes and remember thier netgen IDs

    TNodeToIDMap::iterator n_id = nodeToNetgenID.begin();
    for ( ; n_id != nodeToNetgenID.end(); ++n_id )
    {
        const SMDS_MeshNode* node = n_id->first;

        Netgen_point [ 0 ] = node->X();
        Netgen_point [ 1 ] = node->Y();
        Netgen_point [ 2 ] = node->Z();
        Ng_AddPoint(Netgen_mesh, Netgen_point);
        n_id->second = ++Netgen_NbOfNodes; // set netgen ID

    }

    // set triangles
    list< const SMDS_MeshElement* >::iterator tria = triangles.begin();
    for ( ; tria != triangles.end(); ++tria)
    {
        int i = 0;
        SMDS_ElemIteratorPtr triangleNodesIt = (*tria)->nodesIterator();
        while ( triangleNodesIt->more() ) {
            const SMDS_MeshNode * node =
                static_cast<const SMDS_MeshNode *>(triangleNodesIt->next());
            if(aHelper->IsMedium(node))
                continue;
            Netgen_triangle[ i ] = nodeToNetgenID[ node ];
            ++i;
        }

        Ng_AddSurfaceElement(Netgen_mesh, NG_TRIG, Netgen_triangle);
    }

    // -------------------------
    // Generate the volume mesh
    // -------------------------

    Ng_Meshing_Parameters Netgen_param;

    Netgen_param.secondorder = Netgen_param2ndOrder;
    Netgen_param.fineness = Netgen_paramFine;
    Netgen_param.maxh = Netgen_paramSize;

    Ng_Result status;

    try {
#if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
        OCC_CATCH_SIGNALS;
#endif
        status = Ng_GenerateVolumeMesh(Netgen_mesh, &Netgen_param);
    }
    catch (Standard_Failure& exc) {
        error(COMPERR_OCC_EXCEPTION, exc.GetMessageString());
        status = NG_VOLUME_FAILURE;
    }
    catch (...) {
        error("Bad mesh input!!!");
        status = NG_VOLUME_FAILURE;
    }
    if ( GetComputeError()->IsOK() ) {
        error( status, "Bad mesh input!!!");
    }

    int Netgen_NbOfNodesNew = Ng_GetNP(Netgen_mesh);

    int Netgen_NbOfTetra = Ng_GetNE(Netgen_mesh);

    MESSAGE("End of Volume Mesh Generation. status=" << status <<
            ", nb new nodes: " << Netgen_NbOfNodesNew - Netgen_NbOfNodes <<
            ", nb tetra: " << Netgen_NbOfTetra);

    // -------------------------------------------------------------------
    // Feed back the SMESHDS with the generated Nodes and Volume Elements
    // -------------------------------------------------------------------

    bool isOK = ( Netgen_NbOfTetra > 0 );// get whatever built
    if ( isOK )
    {
        // vector of nodes in which node index == netgen ID
        vector< const SMDS_MeshNode* > nodeVec ( Netgen_NbOfNodesNew + 1 );
        // insert old nodes into nodeVec
        for ( n_id = nodeToNetgenID.begin(); n_id != nodeToNetgenID.end(); ++n_id ) {
            nodeVec.at( n_id->second ) = n_id->first;
        }
        // create and insert new nodes into nodeVec
        int nodeIndex = Netgen_NbOfNodes + 1;

        for ( ; nodeIndex <= Netgen_NbOfNodesNew; ++nodeIndex )
        {
            Ng_GetPoint( Netgen_mesh, nodeIndex, Netgen_point );
            SMDS_MeshNode * node = aHelper->AddNode(Netgen_point[0],
                                                    Netgen_point[1],
                                                    Netgen_point[2]);
            nodeVec.at(nodeIndex) = node;
        }

        // create tetrahedrons
        for ( int elemIndex = 1; elemIndex <= Netgen_NbOfTetra; ++elemIndex )
        {
            Ng_GetVolumeElement(Netgen_mesh, elemIndex, Netgen_tetrahedron);
            aHelper->AddVolume (nodeVec.at( Netgen_tetrahedron[0] ),
                                nodeVec.at( Netgen_tetrahedron[1] ),
                                nodeVec.at( Netgen_tetrahedron[2] ),
                                nodeVec.at( Netgen_tetrahedron[3] ));
        }
    }

    Ng_DeleteMesh(Netgen_mesh);
    Ng_Exit();

    NETGENPlugin_Mesher::RemoveTmpFiles();

    return (status == NG_OK);
}
Пример #3
0
Mesh::MeshObject* Mesher::createMesh() const
{
    // OCC standard mesher
    if (method == Standard) {
        Handle_StlMesh_Mesh aMesh = new StlMesh_Mesh();

        if (!shape.IsNull()) {
            BRepTools::Clean(shape);
#if OCC_VERSION_HEX >= 0x060801
            BRepMesh_IncrementalMesh bMesh(shape, deflection, Standard_False, angularDeflection);
            StlTransfer::RetrieveMesh(shape,aMesh);
#else
            StlTransfer::BuildIncrementalMesh(shape, deflection,
#if OCC_VERSION_HEX >= 0x060503
                Standard_True,
#endif
                aMesh);
#endif
        }

        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 = (static_cast<int>(colors.size()) == aMesh->NbDomains());

        MeshCore::MeshFacetArray faces;
        faces.reserve(aMesh->NbTriangles());

        std::set<Vertex> vertices;
        Standard_Real x1, y1, z1;
        Standard_Real x2, y2, z2;
        Standard_Real x3, y3, z3;

        std::vector< std::vector<unsigned long> > meshSegments;
        std::size_t numMeshFaces = 0;
        StlMesh_MeshExplorer xp(aMesh);
        for (Standard_Integer nbd=1;nbd<=aMesh->NbDomains();nbd++) {
            std::size_t numDomainFaces = 0;
            for (xp.InitTriangle(nbd); xp.MoreTriangle(); xp.NextTriangle()) {
                xp.TriangleVertices(x1,y1,z1,x2,y2,z2,x3,y3,z3);
                std::set<Vertex>::iterator it;
                MeshCore::MeshFacet face;

                // 1st vertex
                Vertex v1(x1,y1,z1);
                it = vertices.find(v1);
                if (it == vertices.end()) {
                    v1.i = vertices.size();
                    face._aulPoints[0] = v1.i;
                    vertices.insert(v1);
                }
                else {
                    face._aulPoints[0] = it->i;
                }

                // 2nd vertex
                Vertex v2(x2,y2,z2);
                it = vertices.find(v2);
                if (it == vertices.end()) {
                    v2.i = vertices.size();
                    face._aulPoints[1] = v2.i;
                    vertices.insert(v2);
                }
                else {
                    face._aulPoints[1] = it->i;
                }

                // 3rd vertex
                Vertex v3(x3,y3,z3);
                it = vertices.find(v3);
                if (it == vertices.end()) {
                    v3.i = vertices.size();
                    face._aulPoints[2] = v3.i;
                    vertices.insert(v3);
                }
                else {
                    face._aulPoints[2] = it->i;
                }

                // make sure that we don't insert invalid facets
                if (face._aulPoints[0] != face._aulPoints[1] &&
                    face._aulPoints[1] != face._aulPoints[2] &&
                    face._aulPoints[2] != face._aulPoints[0]) {
                    faces.push_back(face);
                    numDomainFaces++;
                }
            }

            // add a segment for the face
            if (createSegm || this->segments) {
                std::vector<unsigned long> segment(numDomainFaces);
                std::generate(segment.begin(), segment.end(), Base::iotaGen<unsigned long>(numMeshFaces));
                numMeshFaces += numDomainFaces;
                meshSegments.push_back(segment);
            }
        }

        MeshCore::MeshPointArray verts;
        verts.resize(vertices.size());
        for (auto it : vertices)
            verts[it.i] = it.toPoint();

        MeshCore::MeshKernel kernel;
        kernel.Adopt(verts, faces, true);

        Mesh::MeshObject* meshdata = new Mesh::MeshObject();
        meshdata->swap(kernel);
        if (createSegm) {
            int index = 0;
            for (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());
                meshdata->addSegment(segm);
            }
        }
        else {
            for (auto it : meshSegments) {
                meshdata->addSegment(it);
            }
        }
        return meshdata;
    }

#ifndef HAVE_SMESH
    throw Base::Exception("SMESH is not available on this platform");
#else
    std::list<SMESH_Hypothesis*> hypoth;

    SMESH_Gen* meshgen = SMESH_Gen::get();
    SMESH_Mesh* mesh = meshgen->CreateMesh(0, true);
    int hyp=0;

    switch (method) {
#if defined (HAVE_NETGEN)
    case Netgen: {
        NETGENPlugin_Hypothesis_2D* hyp2d = new NETGENPlugin_Hypothesis_2D(hyp++,0,meshgen);

        if (fineness >=0 && fineness < 5) {
            hyp2d->SetFineness(NETGENPlugin_Hypothesis_2D::Fineness(fineness));
        }
        // user defined values
        else {
            if (growthRate > 0)
                hyp2d->SetGrowthRate(growthRate);
            if (nbSegPerEdge > 0)
                hyp2d->SetNbSegPerEdge(nbSegPerEdge);
            if (nbSegPerRadius > 0)
                hyp2d->SetNbSegPerRadius(nbSegPerRadius);
        }

        hyp2d->SetQuadAllowed(allowquad);
        hyp2d->SetOptimize(optimize);
        hyp2d->SetSecondOrder(secondOrder); // apply bisecting to create four triangles out of one
        hypoth.push_back(hyp2d);

        NETGENPlugin_NETGEN_2D* alg2d = new NETGENPlugin_NETGEN_2D(hyp++,0,meshgen);
        hypoth.push_back(alg2d);
    } break;
#endif
#if defined (HAVE_MEFISTO)
    case Mefisto: {
        if (maxLength > 0) {
            StdMeshers_MaxLength* hyp1d = new StdMeshers_MaxLength(hyp++, 0, meshgen);
            hyp1d->SetLength(maxLength);
            hypoth.push_back(hyp1d);
        }
        else if (localLength > 0) {
            StdMeshers_LocalLength* hyp1d = new StdMeshers_LocalLength(hyp++,0,meshgen);
            hyp1d->SetLength(localLength);
            hypoth.push_back(hyp1d);
        }
        else if (maxArea > 0) {
            StdMeshers_MaxElementArea* hyp2d = new StdMeshers_MaxElementArea(hyp++,0,meshgen);
            hyp2d->SetMaxArea(maxArea);
            hypoth.push_back(hyp2d);
        }
        else if (deflection > 0) {
            StdMeshers_Deflection1D* hyp1d = new StdMeshers_Deflection1D(hyp++,0,meshgen);
            hyp1d->SetDeflection(deflection);
            hypoth.push_back(hyp1d);
        }
        else if (minLen > 0 && maxLen > 0) {
            StdMeshers_Arithmetic1D* hyp1d = new StdMeshers_Arithmetic1D(hyp++,0,meshgen);
            hyp1d->SetLength(minLen, false);
            hyp1d->SetLength(maxLen, true);
            hypoth.push_back(hyp1d);
        }
        else {
            StdMeshers_AutomaticLength* hyp1d = new StdMeshers_AutomaticLength(hyp++,0,meshgen);
            hypoth.push_back(hyp1d);
        }

        {
            StdMeshers_NumberOfSegments* hyp1d = new StdMeshers_NumberOfSegments(hyp++,0,meshgen);
            hyp1d->SetNumberOfSegments(1);
            hypoth.push_back(hyp1d);
        }

        if (regular) {
            StdMeshers_Regular_1D* hyp1d = new StdMeshers_Regular_1D(hyp++,0,meshgen);
            hypoth.push_back(hyp1d);
        }

        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);
    } break;
#endif
    default:
        break;
    }

    // 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; i<hyp;i++)
        mesh->AddHypothesis(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();

    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];

            // Two solutions are possible:
            // <4,6,7>, <4,5,6> or <4,5,7>, <5,6,7>
            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());
        }
    }

    // clean up
    TopoDS_Shape aNull;
    mesh->ShapeToMesh(aNull);
    mesh->Clear();
    delete mesh;
    for (std::list<SMESH_Hypothesis*>::iterator it = hypoth.begin(); it != hypoth.end(); ++it)
        delete *it;
    
    MeshCore::MeshKernel kernel;
    kernel.Adopt(verts, faces, true);

    Mesh::MeshObject* meshdata = new Mesh::MeshObject();
    meshdata->swap(kernel);
    return meshdata;
#endif // HAVE_SMESH
}
Пример #4
0
void ViewProviderFEMMeshBuilder::createMesh(const App::Property* prop, SoCoordinate3* coords, SoIndexedFaceSet* faces) const
{
    const Fem::PropertyFemMesh* mesh = static_cast<const Fem::PropertyFemMesh*>(prop);

    SMESHDS_Mesh* data = const_cast<SMESH_Mesh*>(mesh->getValue().getSMesh())->GetMeshDS();
    const SMDS_MeshInfo& info = data->GetMeshInfo();
    int numNode = info.NbNodes();
    int numTria = info.NbTriangles();
    int numQuad = info.NbQuadrangles();
    //int numPoly = info.NbPolygons();
    //int numVolu = info.NbVolumes();
    int numTetr = info.NbTetras();
    //int numHexa = info.NbHexas();
    //int numPyrd = info.NbPyramids();
    //int numPris = info.NbPrisms();
    //int numHedr = info.NbPolyhedrons();

    int index=0;
    std::map<const SMDS_MeshNode*, int> mapNodeIndex;

    // set the point coordinates
    coords->point.setNum(numNode);
    SMDS_NodeIteratorPtr aNodeIter = data->nodesIterator();
    unsigned int i=0;
    SbVec3f* verts = coords->point.startEditing();
    for (;aNodeIter->more();) {
        const SMDS_MeshNode* aNode = aNodeIter->next();
        verts[i++].setValue((float)aNode->X(),(float)aNode->Y(),(float)aNode->Z());
        mapNodeIndex[aNode] = index++;
    }
    coords->point.finishEditing();

    // set the face indices
    index=0;
    faces->coordIndex.setNum(4*numTria + 5*numQuad + 16*numTetr);
    int32_t* indices = faces->coordIndex.startEditing();
    SMDS_FaceIteratorPtr aFaceIter = data->facesIterator();
    for (;aFaceIter->more();) {
        const SMDS_MeshFace* aFace = aFaceIter->next();
        int num = aFace->NbNodes();
        if (num != 3 && num != 4)
            continue;
        for (int j=0; j<num;j++) {
            const SMDS_MeshNode* node = aFace->GetNode(j);
            indices[index++] = mapNodeIndex[node];
        }
        indices[index++] = SO_END_FACE_INDEX;
    }
    SMDS_VolumeIteratorPtr aVolIter = data->volumesIterator();
    for (;aVolIter->more();) {
        const SMDS_MeshVolume* aVol = aVolIter->next();
        int num = aVol->NbNodes();
        if (num != 4)
            continue;
        int i1 = mapNodeIndex[aVol->GetNode(0)];
        int i2 = mapNodeIndex[aVol->GetNode(1)];
        int i3 = mapNodeIndex[aVol->GetNode(2)];
        int i4 = mapNodeIndex[aVol->GetNode(3)];
        indices[index++] = i1;
        indices[index++] = i3;
        indices[index++] = i2;
        indices[index++] = SO_END_FACE_INDEX;
        indices[index++] = i1;
        indices[index++] = i2;
        indices[index++] = i4;
        indices[index++] = SO_END_FACE_INDEX;
        indices[index++] = i1;
        indices[index++] = i4;
        indices[index++] = i3;
        indices[index++] = SO_END_FACE_INDEX;
        indices[index++] = i2;
        indices[index++] = i3;
        indices[index++] = i4;
        indices[index++] = SO_END_FACE_INDEX;
    }
    faces->coordIndex.finishEditing();
}
Пример #5
0
Mesh::MeshObject* Mesher::createMesh() const
{
#ifndef HAVE_SMESH
    throw Base::Exception("SMESH is not available on this platform");
#else
    std::list<SMESH_Hypothesis*> hypoth;

    SMESH_Gen* meshgen = SMESH_Gen::get();
    SMESH_Mesh* mesh = meshgen->CreateMesh(0, true);
    int hyp=0;

    switch (method) {
#if defined (HAVE_NETGEN)
    case Netgen: {
        NETGENPlugin_Hypothesis_2D* hyp2d = new NETGENPlugin_Hypothesis_2D(hyp++,0,meshgen);

        if (fineness >=0 && fineness < 5) {
            hyp2d->SetFineness(NETGENPlugin_Hypothesis_2D::Fineness(fineness));
        }
        // user defined values
        else {
            if (growthRate > 0)
                hyp2d->SetGrowthRate(growthRate);
            if (nbSegPerEdge > 0)
                hyp2d->SetNbSegPerEdge(nbSegPerEdge);
            if (nbSegPerRadius > 0)
                hyp2d->SetNbSegPerRadius(nbSegPerRadius);
        }

        hyp2d->SetQuadAllowed(allowquad);
        hyp2d->SetOptimize(optimize);
        hyp2d->SetSecondOrder(secondOrder); // apply bisecting to create four triangles out of one
        hypoth.push_back(hyp2d);

        NETGENPlugin_NETGEN_2D* alg2d = new NETGENPlugin_NETGEN_2D(hyp++,0,meshgen);
        hypoth.push_back(alg2d);
    } break;
#endif
#if defined (HAVE_MEFISTO)
    case Mefisto: {
        if (maxLength > 0) {
            StdMeshers_MaxLength* hyp1d = new StdMeshers_MaxLength(hyp++, 0, meshgen);
            hyp1d->SetLength(maxLength);
            hypoth.push_back(hyp1d);
        }
        else if (localLength > 0) {
            StdMeshers_LocalLength* hyp1d = new StdMeshers_LocalLength(hyp++,0,meshgen);
            hyp1d->SetLength(localLength);
            hypoth.push_back(hyp1d);
        }
        else if (maxArea > 0) {
            StdMeshers_MaxElementArea* hyp2d = new StdMeshers_MaxElementArea(hyp++,0,meshgen);
            hyp2d->SetMaxArea(maxArea);
            hypoth.push_back(hyp2d);
        }
        else if (deflection > 0) {
            StdMeshers_Deflection1D* hyp1d = new StdMeshers_Deflection1D(hyp++,0,meshgen);
            hyp1d->SetDeflection(deflection);
            hypoth.push_back(hyp1d);
        }
        else if (minLen > 0 && maxLen > 0) {
            StdMeshers_Arithmetic1D* hyp1d = new StdMeshers_Arithmetic1D(hyp++,0,meshgen);
            hyp1d->SetLength(minLen, false);
            hyp1d->SetLength(maxLen, true);
            hypoth.push_back(hyp1d);
        }
        else {
            StdMeshers_AutomaticLength* hyp1d = new StdMeshers_AutomaticLength(hyp++,0,meshgen);
            hypoth.push_back(hyp1d);
        }

        {
            StdMeshers_NumberOfSegments* hyp1d = new StdMeshers_NumberOfSegments(hyp++,0,meshgen);
            hyp1d->SetNumberOfSegments(1);
            hypoth.push_back(hyp1d);
        }

        if (regular) {
            StdMeshers_Regular_1D* hyp1d = new StdMeshers_Regular_1D(hyp++,0,meshgen);
            hypoth.push_back(hyp1d);
        }

        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);
    } break;
#endif
    default:
        break;
    }

    // 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; i<hyp;i++)
        mesh->AddHypothesis(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();

    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];

            // Two solutions are possible:
            // <4,6,7>, <4,5,6> or <4,5,7>, <5,6,7>
            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());
        }
    }

    // clean up
    TopoDS_Shape aNull;
    mesh->ShapeToMesh(aNull);
    mesh->Clear();
    delete mesh;
    for (std::list<SMESH_Hypothesis*>::iterator it = hypoth.begin(); it != hypoth.end(); ++it)
        delete *it;
    
    MeshCore::MeshKernel kernel;
    kernel.Adopt(verts, faces, true);

    Mesh::MeshObject* meshdata = new Mesh::MeshObject();
    meshdata->swap(kernel);
    return meshdata;
#endif // HAVE_SMESH
}