From 2e0c2800141c3194ab72076de198791c8e3ac76b Mon Sep 17 00:00:00 2001 From: eap Date: Wed, 18 May 2005 07:29:05 +0000 Subject: [PATCH] Fix Bug PAL8787: pass to Netgen only nodes of triangles --- src/NETGENPlugin/NETGENPlugin_NETGEN_3D.cxx | 761 ++++---------------- 1 file changed, 151 insertions(+), 610 deletions(-) diff --git a/src/NETGENPlugin/NETGENPlugin_NETGEN_3D.cxx b/src/NETGENPlugin/NETGENPlugin_NETGEN_3D.cxx index 0f7eb7f..db0c493 100644 --- a/src/NETGENPlugin/NETGENPlugin_NETGEN_3D.cxx +++ b/src/NETGENPlugin/NETGENPlugin_NETGEN_3D.cxx @@ -10,27 +10,22 @@ using namespace std; #include "NETGENPlugin_NETGEN_3D.hxx" + #include "SMESH_Gen.hxx" #include "SMESH_Mesh.hxx" -#include "SMESH_subMesh.hxx" - +#include "SMESH_ControlsDef.hxx" +#include "SMESHDS_Mesh.hxx" #include "SMDS_MeshElement.hxx" #include "SMDS_MeshNode.hxx" -#include "SMDS_FacePosition.hxx" #include -#include -#include -#include -#include - -#include -#include -#include -#include #include "utilities.h" +#include +#include +#include + /* Netgen include files */ @@ -100,8 +95,6 @@ bool NETGENPlugin_NETGEN_3D::CheckHypothesis theHyp = (*itl); // use only the first hypothesis string hypName = theHyp->GetName(); -// int hypId = theHyp->GetID(); -// SCRUTE(hypName); bool isOk = false; @@ -132,631 +125,179 @@ bool NETGENPlugin_NETGEN_3D::Compute(SMESH_Mesh& aMesh, SMESHDS_Mesh* meshDS = aMesh.GetMeshDS(); - map netgenToDS; + // get a shell from aShape + TopoDS_Shell aShell; + TopExp_Explorer exp(aShape,TopAbs_SHELL); + if ( exp.More() ) + aShell = TopoDS::Shell(exp.Current()); - // check if all faces were meshed by a triangle mesher (here MESFISTO_2D) + if ( aShell.IsNull() || !aMesh.GetSubMesh( aShell )) { + INFOS( "NETGENPlugin_NETGEN_3D::Compute(), bad shape"); + return false; + } + // ------------------------------------------------------------------- + // get triangles on aShell and make a map of nodes to Netgen node IDs + // ------------------------------------------------------------------- - vector meshFaces; - vector shapeFaces; + typedef map< const SMDS_MeshNode*, int> TNodeToIDMap; + TNodeToIDMap nodeToNetgenID; + list< const SMDS_MeshElement* > triangles; + list< bool > isReversed; // orientation of triangles + + SMESH::Controls::Area areaControl; + SMESH::Controls::TSequenceOfXYZ nodesCoords; for (TopExp_Explorer exp(aShape,TopAbs_FACE);exp.More();exp.Next()) + { + TopoDS_Shape aShapeFace = exp.Current(); + int faceID = meshDS->ShapeToIndex( aShapeFace ); + TopoDS_Shape aMeshedFace = meshDS->IndexToShape( faceID ); + const SMESHDS_SubMesh * aSubMeshDSFace = meshDS->MeshElements( faceID ); + if ( aSubMeshDSFace ) { - TopoDS_Shape aShapeFace = exp.Current(); - SMESH_subMesh* aSubMesh = aMesh.GetSubMeshContaining(exp.Current()); - ASSERT (aSubMesh); - int internal_size = meshFaces.size(); - int index = 0; - for (int i = 0;iGetElements(); + while ( iteratorElem->more() ) // loop on elements on a face + { + // check element + const SMDS_MeshElement* elem = iteratorElem->next(); + if ( !elem || elem->NbNodes() != 3 ) { + INFOS( "NETGENPlugin_NETGEN_3D::Compute(), bad mesh"); + return false; + } + // keep a triangle + triangles.push_back( elem ); + isReversed.push_back( isRev ); + // put elem nodes to nodeToNetgenID map + SMDS_ElemIteratorPtr triangleNodesIt = elem->nodesIterator(); + while ( triangleNodesIt->more() ) { + const SMDS_MeshNode * node = + static_cast(triangleNodesIt->next()); + nodeToNetgenID.insert( make_pair( node, 0 )); + } +#ifdef _DEBUG_ + // check if a trainge is degenerated + areaControl.GetPoints( elem, nodesCoords ); + double area = areaControl.GetValue( nodesCoords ); + if ( area <= DBL_MIN ) { + MESSAGE( "Warning: Degenerated " << elem ); + } +#endif + } } + } + // --------------------------------- + // Feed the Netgen with surface mesh + // --------------------------------- - int numberOfFaces = meshFaces.size(); + int Netgen_NbOfNodes = nodeToNetgenID.size(); + int Netgen_param2ndOrder = 0; + double Netgen_paramFine = 1.; + double Netgen_paramSize = _maxElementVolume; - int NbTotOfTria = 0; - int NbTotOfNodesFaces = 0; + double Netgen_point[3]; + int Netgen_triangle[3]; + int Netgen_tetrahedron[4]; - for (int i=0; iGetSubShape(); - TopoDS_Shape aFace = shapeFaces[i]; - SMESH_Algo* algoFace = _gen->GetAlgo(aMesh, aShapeFace); - string algoFaceName = algoFace->GetName(); - if (algoFaceName != "MEFISTO_2D") - { - INFOS(algoFaceName); - return false; - } - - const SMESHDS_SubMesh* aSubMeshDSFace = meshFaces[i]->GetSubMeshDS(); - - int nbNodes = aSubMeshDSFace->NbNodes(); - NbTotOfNodesFaces += nbNodes; - int nbTria = aSubMeshDSFace->NbElements(); - NbTotOfTria += nbTria; - int index = 0; - - SMDS_ElemIteratorPtr iteratorTriangle = aSubMeshDSFace->GetElements(); - - index = 0; - int numberOfDegeneratedTriangle = 0; - while(iteratorTriangle->more()) - { - index++; - const SMDS_MeshElement * triangle = iteratorTriangle->next(); - - SMDS_ElemIteratorPtr triangleNodesIt = triangle->nodesIterator(); - - const SMDS_MeshNode * node1 = static_cast(triangleNodesIt->next()); - double node1X = node1->X(); - double node1Y = node1->Y(); - double node1Z = node1->Z(); - - const SMDS_MeshNode * node2 = static_cast(triangleNodesIt->next()); - double node2X = node2->X(); - double node2Y = node2->Y(); - double node2Z = node2->Z(); - - const SMDS_MeshNode * node3 = static_cast(triangleNodesIt->next()); - double node3X = node3->X(); - double node3Y = node3->Y(); - double node3Z = node3->Z(); - - // Compute the triangle surface - - double vect1 = ((node2Y - node1Y)*(node3Z - node1Z) - (node2Z - node1Z)*(node3Y - node1Y)); - double vect2 = - ((node2X - node1X)*(node3Z - node1Z) - (node2Z - node1Z)*(node3X - node1X)); - double vect3 = ((node2X - node1X)*(node3Y - node1Y) - (node2Y - node1Y)*(node3X - node1X)); - double epsilon = 1.0e-6; - - bool triangleIsDegenerated = ((abs(vect1) 0) - MESSAGE("WARNING THERE IS(ARE) " << numberOfDegeneratedTriangle << " degenerated triangle on this face"); + Ng_Init(); - } - - // check if all edges were meshed by a edge mesher (here Regular_1D) + Ng_Mesh * Netgen_mesh = Ng_NewMesh(); - vector meshEdges; - for (TopExp_Explorer exp(aShape,TopAbs_EDGE);exp.More();exp.Next()) - { - SMESH_subMesh* aSubMesh = aMesh.GetSubMeshContaining(exp.Current()); - ASSERT (aSubMesh); - int internal_size = meshEdges.size(); - int index = 0; - for (int i = 0;ifirst; + Netgen_point [ 0 ] = node->X(); + Netgen_point [ 1 ] = node->Y(); + Netgen_point [ 2 ] = node->Z(); + n_id->second = ++id; + Ng_AddPoint(Netgen_mesh, Netgen_point); + } + // set triangles + list< const SMDS_MeshElement* >::iterator tria = triangles.begin(); + list< bool >::iterator reverse = isReversed.begin(); + for ( ; tria != triangles.end(); ++tria, ++reverse ) + { + int i = 0; + SMDS_ElemIteratorPtr triangleNodesIt = (*tria)->nodesIterator(); + while ( triangleNodesIt->more() ) { + const SMDS_MeshNode * node = + static_cast(triangleNodesIt->next()); + Netgen_triangle[ *reverse ? 2 - i : i ] = nodeToNetgenID[ node ]; + ++i; } + Ng_AddSurfaceElement(Netgen_mesh, NG_TRIG, Netgen_triangle); + } - int numberOfEdges = meshEdges.size(); - - int NbTotOfNodesEdges = 0; - int NbTotOfSegs = 0; + // ------------------------- + // Generate the volume mesh + // ------------------------- - for (int i=0; iGetSubShape(); - SMESH_Algo* algoEdge = _gen->GetAlgo(aMesh, aShapeEdge); - string algoEdgeName = algoEdge->GetName(); - if (algoEdgeName != "Regular_1D") - { - INFOS(algoEdgeName); - ASSERT(0); - return false; - } - - const SMESHDS_SubMesh* aSubMeshDSEdge = meshEdges[i]->GetSubMeshDS(); - - int nbNodes = aSubMeshDSEdge->NbNodes(); - NbTotOfNodesEdges += nbNodes; - int nbSegs = aSubMeshDSEdge->NbElements(); - NbTotOfSegs += nbSegs; - } + Ng_Meshing_Parameters Netgen_param; - vector meshVertices; - for (TopExp_Explorer exp(aShape,TopAbs_VERTEX);exp.More();exp.Next()) - { - SMESH_subMesh* aSubMesh = aMesh.GetSubMeshContaining(exp.Current()); - ASSERT (aSubMesh); - int internal_size = meshVertices.size(); - int index = 0; - for (int i = 0;iGetSubShape(); + int Netgen_NbOfNodesNew = Ng_GetNP(Netgen_mesh); - const SMESHDS_SubMesh * aSubMeshDSVertex = meshVertices[i]->GetSubMeshDS(); + int Netgen_NbOfTetra = Ng_GetNE(Netgen_mesh); - int nbNodes = aSubMeshDSVertex->NbNodes(); - NbTotOfNodesVertices += nbNodes; - } + MESSAGE("End of Volume Mesh Generation. status=" << status << + ", nb new nodes: " << Netgen_NbOfNodesNew - Netgen_NbOfNodes << + ", nb tetra: " << Netgen_NbOfTetra); - vector meshShells; - TopoDS_Shell aShell; + // ------------------------------------------------------------------- + // Feed back the SMESHDS with the generated Nodes and Volume Elements + // ------------------------------------------------------------------- - for (TopExp_Explorer exp(aShape,TopAbs_SHELL);exp.More();exp.Next()) + bool isOK = ( status == NG_OK && Netgen_NbOfTetra > 0 ); + 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[ n_id->second ] = n_id->first; + // create and insert new nodes into nodeVec + int nodeIndex = Netgen_NbOfNodes; + for ( ; nodeIndex <= Netgen_NbOfNodesNew; ++nodeIndex ) { - SMESH_subMesh* aSubMesh = aMesh.GetSubMesh(exp.Current()); - ASSERT(aSubMesh); - aShell = TopoDS::Shell(exp.Current()); - meshShells.push_back(aSubMesh); + Ng_GetPoint( Netgen_mesh, nodeIndex, Netgen_point ); + SMDS_MeshNode * node = meshDS->AddNode(Netgen_point[0], + Netgen_point[1], + Netgen_point[2]); + meshDS->SetNodeInVolume(node, aShell); + nodeVec[nodeIndex] = node; } - int numberOfShells = meshShells.size(); - - if (numberOfShells > 0) + // create tetrahedrons + for ( int elemIndex = 1; elemIndex <= Netgen_NbOfTetra; ++elemIndex ) { - /* - Prepare the Netgen surface mesh from the SMESHDS - */ - int spaceDimension = 3; - int nbNodesByTri = 3; - int nbNodesByTetra = 4; - - int Netgen_NbOfNodes = NbTotOfNodesFaces + - NbTotOfNodesEdges + - NbTotOfNodesVertices; - int Netgen_NbOfTria = NbTotOfTria; - int Netgen_param2ndOrder = 0; - double Netgen_paramFine = 1.; - double Netgen_paramSize = _maxElementVolume; - - double * Netgen_Coordinates = new double [spaceDimension* - Netgen_NbOfNodes]; - int * listNodeCoresNetgenSmesh = new int [Netgen_NbOfNodes]; - int * Netgen_Connectivity = new int [nbNodesByTri*Netgen_NbOfTria]; - double * Netgen_point = new double [spaceDimension]; - int * Netgen_triangle = new int [nbNodesByTri]; - int * Netgen_tetrahedron = new int [nbNodesByTetra]; - - for (int i=0; iGetSubMeshDS(); - - SMDS_NodeIteratorPtr iteratorNodes = aSubMeshDSVertex->GetNodes(); - - while(iteratorNodes->more()) - { - const SMDS_MeshNode * node = iteratorNodes->next(); - int nodeId = node->GetID(); - double nodeX = node->X(); - double nodeY = node->Y(); - double nodeZ = node->Z(); - listNodeCoresNetgenSmesh[indexNodes] = nodeId; - int index = indexNodes*spaceDimension; - Netgen_Coordinates[index] = nodeX; - Netgen_Coordinates[index+1] = nodeY; - Netgen_Coordinates[index+2] = nodeZ; - netgenToDS[indexNodes] = node; - indexNodes++; - } - } - - for (int i=0; iGetSubMeshDS(); - - SMDS_NodeIteratorPtr iteratorNodes = aSubMeshDSEdge->GetNodes(); - - while(iteratorNodes->more()) - { - const SMDS_MeshNode * node = iteratorNodes->next(); - listNodeCoresNetgenSmesh[indexNodes] = node->GetID(); - int index = indexNodes*spaceDimension; - Netgen_Coordinates[index] = node->X(); - Netgen_Coordinates[index+1] = node->Y(); - Netgen_Coordinates[index+2] = node->Z(); - netgenToDS[indexNodes] = node; - indexNodes++; - } - } - - for (int i=0; iGetSubMeshDS(); - - SMDS_NodeIteratorPtr iteratorNodes = aSubMeshDSFace->GetNodes(); - - while(iteratorNodes->more()) - { - const SMDS_MeshNode * node = iteratorNodes->next(); - int nodeId = node->GetID(); - double nodeX = node->X(); - double nodeY = node->Y(); - double nodeZ = node->Z(); -// MESSAGE("NODE -> ID = " << nodeId << " X = " << nodeX << " Y = " << nodeY << " Z = " << nodeZ); - listNodeCoresNetgenSmesh[indexNodes] = nodeId; - int index = indexNodes*spaceDimension; - Netgen_Coordinates[index] = nodeX; - Netgen_Coordinates[index+1] = nodeY; - Netgen_Coordinates[index+2] = nodeZ; - netgenToDS[indexNodes] = node; - indexNodes++; - } - } - - for (int i=0; iGetSubMeshDS(); - - TopoDS_Shape aFace = shapeFaces[i]; - - SMDS_ElemIteratorPtr iteratorTriangle = aSubMeshDSFace->GetElements(); - - TopoDS_Shape aShapeFace = meshFaces[i]->GetSubShape(); - - bool orientationMeshFace = (aFace.Orientation() == aShapeFace.Orientation()); - - if (orientationMeshFace) - { - while(iteratorTriangle->more()) - { - const SMDS_MeshElement * triangle = iteratorTriangle->next(); - - SMDS_ElemIteratorPtr triangleNodesIt = triangle->nodesIterator(); - - int triangleNode1 = (triangleNodesIt->next())->GetID(); - int triangleNode2 = (triangleNodesIt->next())->GetID(); - int triangleNode3 = (triangleNodesIt->next())->GetID(); - - int N1New = 0; - int N2New = 0; - int N3New = 0; - int index = indexTrias*nbNodesByTri; - - for (int j=0; jmore()) - { - const SMDS_MeshElement * triangle = iteratorTriangle->next(); - - SMDS_ElemIteratorPtr triangleNodesIt = triangle->nodesIterator(); - - int triangleNode1 = (triangleNodesIt->next())->GetID(); - int triangleNode3 = (triangleNodesIt->next())->GetID(); - int triangleNode2 = (triangleNodesIt->next())->GetID(); - - int N1New = 0; - int N2New = 0; - int N3New = 0; - int index = indexTrias*nbNodesByTri; - - for (int j=0; j=1) && (Nij<=Netgen_NbOfNodes)); - - nodesUsed[Nij-1] = 1; - Netgen_Connectivity[i*nbNodesByTri+j] = Nij; - } - - for (int i=0; iAddNode(Netgen_CoordinatesNew[index], - Netgen_CoordinatesNew[index+1], - Netgen_CoordinatesNew[index+2]); - - meshDS->SetNodeInVolume(node, aShell); - - index = i+Netgen_NbOfNodes; - netgenToDS[index] = node; - - listNodeShellCoresNetgenSmesh[i] = node->GetID(); - } - - for (int i=0; iAddVolume(node1,node2,node3,node4); - - meshDS->SetMeshElementOnShape(elt, aShell); - } - - /* - Free the memory needed by to generate the Netgen Mesh - */ - - delete [] Netgen_Coordinates; - delete [] Netgen_Connectivity; - delete [] Netgen_CoordinatesNew; - delete [] Netgen_ConnectivityNew; - delete [] Netgen_point; - delete [] Netgen_triangle; - delete [] Netgen_tetrahedron; - - delete [] listNodeCoresNetgenSmesh; - delete [] listNodeShellCoresNetgenSmesh; - - Ng_DeleteMesh(Netgen_mesh); - Ng_Exit(); - - return true; + Ng_GetVolumeElement(Netgen_mesh, elemIndex, Netgen_tetrahedron); + SMDS_MeshVolume * elt = meshDS->AddVolume (nodeVec[ Netgen_tetrahedron[0] ], + nodeVec[ Netgen_tetrahedron[1] ], + nodeVec[ Netgen_tetrahedron[2] ], + nodeVec[ Netgen_tetrahedron[3] ]); + meshDS->SetMeshElementOnShape(elt, aShell); } + } - return false; -} + Ng_DeleteMesh(Netgen_mesh); + Ng_Exit(); + return isOK; +} //============================================================================= /*! -- 2.39.2