From: gdd Date: Fri, 8 Apr 2011 15:38:23 +0000 (+0000) Subject: Still in progress ... X-Git-Url: http://git.salome-platform.org/gitweb/?a=commitdiff_plain;h=6070a22a8886344099ee2d127c996f431e9a79ec;p=plugins%2Fghs3dplugin.git Still in progress ... --- diff --git a/src/GHS3DPlugin/GHS3DPlugin_GHS3D.cxx b/src/GHS3DPlugin/GHS3DPlugin_GHS3D.cxx index 7cbfa81..5e5cf53 100644 --- a/src/GHS3DPlugin/GHS3DPlugin_GHS3D.cxx +++ b/src/GHS3DPlugin/GHS3DPlugin_GHS3D.cxx @@ -26,10 +26,6 @@ // #include "GHS3DPlugin_GHS3D.hxx" #include "GHS3DPlugin_Hypothesis.hxx" -extern "C" -{ - #include "libmesh5.h" -} #include @@ -51,7 +47,9 @@ extern "C" #include #include +#include #include +#include #include #include #include @@ -79,6 +77,7 @@ extern "C" #else #include #endif +#include using namespace std; @@ -185,13 +184,13 @@ bool GHS3DPlugin_GHS3D::CheckHypothesis ( SMESH_Mesh& aMesh, return true; } -#if GHS3D_VERSION < 42 +#if GHS3D_VERSION < 42 || !defined GMF_HAS_SUBDOMAIN_INFO //======================================================================= //function : findShape //purpose : //======================================================================= -static TopoDS_Shape findShape(const SMDS_MeshNode *aNode[], +static TopoDS_Shape findShape(SMDS_MeshNode *aNode[], TopoDS_Shape aShape, const TopoDS_Shape shape[], double** box, @@ -244,23 +243,722 @@ static char* readMapIntLine(char* ptr, int tab[]) { } return ptr; } + +//================================================================================ +/*! + * \brief returns true if a triangle defined by the nodes is a temporary face on a + * side facet of pyramid and defines sub-domian inside the pyramid + */ +//================================================================================ + +static bool isTmpFace(const SMDS_MeshNode* node1, + const SMDS_MeshNode* node2, + const SMDS_MeshNode* node3) +{ + // find a pyramid sharing the 3 nodes + //const SMDS_MeshElement* pyram = 0; + SMDS_ElemIteratorPtr vIt1 = node1->GetInverseElementIterator(SMDSAbs_Volume); + while ( vIt1->more() ) + { + const SMDS_MeshElement* pyram = vIt1->next(); + if ( pyram->NbCornerNodes() != 5 ) continue; + int i2, i3; + if ( (i2 = pyram->GetNodeIndex( node2 )) >= 0 && + (i3 = pyram->GetNodeIndex( node3 )) >= 0 ) + { + // Triangle defines sub-domian inside the pyramid if it's + // normal points out of the pyram + + // make i2 and i3 hold indices of base nodes of the pyram while + // keeping the nodes order in the triangle + const int iApex = 4; + if ( i2 == iApex ) + i2 = i3, i3 = pyram->GetNodeIndex( node1 ); + else if ( i3 == iApex ) + i3 = i2, i2 = pyram->GetNodeIndex( node1 ); + + int i3base = (i2+1) % 4; // next index after i2 within the pyramid base + return ( i3base != i3 ); + } + } + return false; +} + +//======================================================================= +//function : findShapeID +//purpose : find the solid corresponding to GHS3D sub-domain following +// the technique proposed in GHS3D manual (available within +// ghs3d installation) in chapter "B.4 Subdomain (sub-region) assignment". +// In brief: normal of the triangle defined by the given nodes +// points out of the domain it is associated to +//======================================================================= + +static int findShapeID(SMESH_Mesh& mesh, + const SMDS_MeshNode* node1, + const SMDS_MeshNode* node2, + const SMDS_MeshNode* node3, + const bool toMeshHoles) +{ + const int invalidID = 0; + SMESHDS_Mesh* meshDS = mesh.GetMeshDS(); + + // face the nodes belong to + const SMDS_MeshElement * face = meshDS->FindFace(node1,node2,node3); + if ( !face ) + return isTmpFace(node1, node2, node3) ? HOLE_ID : invalidID; +#ifdef _DEBUG_ + std::cout << "bnd face " << face->GetID() << " - "; +#endif + // geom face the face assigned to + SMESH_MeshEditor editor(&mesh); + int geomFaceID = editor.FindShape( face ); + if ( !geomFaceID ) + return isTmpFace(node1, node2, node3) ? HOLE_ID : invalidID; + TopoDS_Shape shape = meshDS->IndexToShape( geomFaceID ); + if ( shape.IsNull() || shape.ShapeType() != TopAbs_FACE ) + return invalidID; + TopoDS_Face geomFace = TopoDS::Face( shape ); + + // solids bounded by geom face + TopTools_IndexedMapOfShape solids, shells; + TopTools_ListIteratorOfListOfShape ansIt = mesh.GetAncestors(geomFace); + for ( ; ansIt.More(); ansIt.Next() ) { + switch ( ansIt.Value().ShapeType() ) { + case TopAbs_SOLID: + solids.Add( ansIt.Value() ); break; + case TopAbs_SHELL: + shells.Add( ansIt.Value() ); break; + default:; + } + } + // analyse found solids + if ( solids.Extent() == 0 || shells.Extent() == 0) + return invalidID; + + const TopoDS_Solid& solid1 = TopoDS::Solid( solids(1) ); + if ( solids.Extent() == 1 ) + { + if ( toMeshHoles ) + return meshDS->ShapeToIndex( solid1 ); + + // - Are we at a hole boundary face? + if ( shells(1).IsSame( BRepTools::OuterShell( solid1 )) ) + { // - No, but maybe a hole is bound by two shapes? Does shells(1) touches another shell? + bool touch = false; + TopExp_Explorer eExp( shells(1), TopAbs_EDGE ); + // check if any edge of shells(1) belongs to another shell + for ( ; eExp.More() && !touch; eExp.Next() ) { + ansIt = mesh.GetAncestors( eExp.Current() ); + for ( ; ansIt.More() && !touch; ansIt.Next() ) { + if ( ansIt.Value().ShapeType() == TopAbs_SHELL ) + touch = ( !ansIt.Value().IsSame( shells(1) )); + } + } + if (!touch) + return meshDS->ShapeToIndex( solid1 ); + } + } + // find orientation of geom face within the first solid + TopExp_Explorer fExp( solid1, TopAbs_FACE ); + for ( ; fExp.More(); fExp.Next() ) + if ( geomFace.IsSame( fExp.Current() )) { + geomFace = TopoDS::Face( fExp.Current() ); + break; + } + if ( !fExp.More() ) + return invalidID; // face not found + + // normale to triangle + gp_Pnt node1Pnt ( node1->X(), node1->Y(), node1->Z() ); + gp_Pnt node2Pnt ( node2->X(), node2->Y(), node2->Z() ); + gp_Pnt node3Pnt ( node3->X(), node3->Y(), node3->Z() ); + gp_Vec vec12( node1Pnt, node2Pnt ); + gp_Vec vec13( node1Pnt, node3Pnt ); + gp_Vec meshNormal = vec12 ^ vec13; + if ( meshNormal.SquareMagnitude() < DBL_MIN ) + return invalidID; + + // get normale to geomFace at any node + bool geomNormalOK = false; + gp_Vec geomNormal; + const SMDS_MeshNode* nodes[3] = { node1, node2, node3 }; + SMESH_MesherHelper helper( mesh ); helper.SetSubShape( geomFace ); + for ( int i = 0; !geomNormalOK && i < 3; ++i ) + { + // find UV of i-th node on geomFace + const SMDS_MeshNode* nNotOnSeamEdge = 0; + if ( helper.IsSeamShape( nodes[i]->getshapeId() )) { + if ( helper.IsSeamShape( nodes[(i+1)%3]->getshapeId() )) + nNotOnSeamEdge = nodes[(i+2)%3]; + else + nNotOnSeamEdge = nodes[(i+1)%3]; + } + bool uvOK; + gp_XY uv = helper.GetNodeUV( geomFace, nodes[i], nNotOnSeamEdge, &uvOK ); + // check that uv is correct + if (uvOK) { + double tol = 1e-6; + TopoDS_Shape nodeShape = helper.GetSubShapeByNode( nodes[i], meshDS ); + if ( !nodeShape.IsNull() ) + switch ( nodeShape.ShapeType() ) + { + case TopAbs_FACE: tol = BRep_Tool::Tolerance( TopoDS::Face( nodeShape )); break; + case TopAbs_EDGE: tol = BRep_Tool::Tolerance( TopoDS::Edge( nodeShape )); break; + case TopAbs_VERTEX: tol = BRep_Tool::Tolerance( TopoDS::Vertex( nodeShape )); break; + default:; + } + gp_Pnt nodePnt ( nodes[i]->X(), nodes[i]->Y(), nodes[i]->Z() ); + BRepAdaptor_Surface surface( geomFace ); + uvOK = ( nodePnt.Distance( surface.Value( uv.X(), uv.Y() )) < 2 * tol ); + if ( uvOK ) { + // normale to geomFace at UV + gp_Vec du, dv; + surface.D1( uv.X(), uv.Y(), nodePnt, du, dv ); + geomNormal = du ^ dv; + if ( geomFace.Orientation() == TopAbs_REVERSED ) + geomNormal.Reverse(); + geomNormalOK = ( geomNormal.SquareMagnitude() > DBL_MIN * 1e3 ); + } + } + } + if ( !geomNormalOK) + return invalidID; + + // compare normals + bool isReverse = ( meshNormal * geomNormal ) < 0; + if ( !isReverse ) + return meshDS->ShapeToIndex( solid1 ); + + if ( solids.Extent() == 1 ) + return HOLE_ID; // we are inside a hole + else + return meshDS->ShapeToIndex( solids(2) ); +} +#endif + +//======================================================================= +//function : countShape +//purpose : +//======================================================================= + +template < class Mesh, class Shape > +static int countShape( Mesh* mesh, Shape shape ) { + TopExp_Explorer expShape ( mesh->ShapeToMesh(), shape ); + TopTools_MapOfShape mapShape; + int nbShape = 0; + for ( ; expShape.More(); expShape.Next() ) { + if (mapShape.Add(expShape.Current())) { + nbShape++; + } + } + return nbShape; +} + +//======================================================================= +//function : getShape +//purpose : +//======================================================================= + +template < class Mesh, class Shape, class Tab > +void getShape(Mesh* mesh, Shape shape, Tab *t_Shape) { + TopExp_Explorer expShape ( mesh->ShapeToMesh(), shape ); + TopTools_MapOfShape mapShape; + for ( int i=0; expShape.More(); expShape.Next() ) { + if (mapShape.Add(expShape.Current())) { + t_Shape[i] = expShape.Current(); + i++; + } + } + return; +} + +//======================================================================= +//function : findEdgeID +//purpose : +//======================================================================= + +static int findEdgeID(const SMDS_MeshNode* aNode, + const SMESHDS_Mesh* theMesh, + const int nEdge, + const TopoDS_Shape* t_Edge) { + + TopoDS_Shape aPntShape, foundEdge; + TopoDS_Vertex aVertex; + gp_Pnt aPnt( aNode->X(), aNode->Y(), aNode->Z() ); + + int foundInd, ind; + double nearest = RealLast(), *t_Dist; + double epsilon = Precision::Confusion(); + + t_Dist = new double[ nEdge ]; + aPntShape = BRepBuilderAPI_MakeVertex( aPnt ).Shape(); + aVertex = TopoDS::Vertex( aPntShape ); + + for ( ind=0; ind < nEdge; ind++ ) { + BRepExtrema_DistShapeShape aDistance ( aVertex, t_Edge[ind] ); + t_Dist[ind] = aDistance.Value(); + if ( t_Dist[ind] < nearest ) { + nearest = t_Dist[ind]; + foundEdge = t_Edge[ind]; + foundInd = ind; + if ( nearest < epsilon ) + ind = nEdge; + } + } + + delete [] t_Dist; + return theMesh->ShapeToIndex( foundEdge ); +} + +#if GHS3D_VERSION >= 42 +//======================================================================= +//function : readGMFFile +//purpose : +//======================================================================= + +static bool readGMFFile( +#ifndef GMF_HAS_SUBDOMAIN_INFO + const int fileOpen, +#endif + const char* theFileName, + SMESH_Mesh& theMesh, + const int nbShape, + const TopoDS_Shape* tabShape, + double** tabBox, + map & theGhs3dIdToNodeMap, + bool toMeshHoles, + int nbEnforcedVertices, + int nbEnforcedNodes, + TIDSortedNodeSet & theEnforcedNodes, + TIDSortedElemSet & theEnforcedTriangles, + TIDSortedElemSet & theEnforcedQuadrangles) +{ + TopoDS_Shape aShape; + TopoDS_Vertex aVertex; + SMESHDS_Mesh* theMeshDS = theMesh.GetMeshDS(); + int nbElem = 0, nbRef = 0, IdShapeRef = 1; + int *tabID; + int aGMFNodeID = 0; + int compoundID = + nbShape ? theMeshDS->ShapeToIndex( tabShape[0] ) : theMeshDS->ShapeToIndex( theMeshDS->ShapeToMesh() ); + int tetraShapeID = compoundID; + double epsilon = Precision::Confusion(); + int *nodeAssigne, *GMFNodeAssigne; + SMDS_MeshNode** GMFNode; + TopoDS_Shape *tabCorner, *tabEdge; + std::map tabRef; + + + int ver, dim; + MESSAGE("Read " << theFileName << " file"); + int InpMsh = GmfOpenMesh(theFileName, GmfRead, &ver, &dim); + if (!InpMsh) + return false; + + // =========================== + // Fill the tabID array: BEGIN + // =========================== + +#ifndef GMF_HAS_SUBDOMAIN_INFO + /* + The output .mesh file does not contain yet the subdomain-info (Ghs3D 4.2) + */ + Kernel_Utils::Localizer loc; + struct stat status; + size_t length; + + char *ptr, *mapPtr; + char *tetraPtr; + int *tab = new int[3]; + + // Read the file state + fstat(fileOpen, &status); + length = status.st_size; + + // Mapping the result file into memory +#ifdef WNT + HANDLE fd = CreateFile(theFileName, GENERIC_READ, FILE_SHARE_READ, + NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); + HANDLE hMapObject = CreateFileMapping(fd, NULL, PAGE_READONLY, + 0, (DWORD)length, NULL); + ptr = ( char* ) MapViewOfFile(hMapObject, FILE_MAP_READ, 0, 0, 0 ); +#else + ptr = (char *) mmap(0,length,PROT_READ,MAP_PRIVATE,fileOpen,0); +#endif + mapPtr = ptr; + + ptr = readMapIntLine(ptr, tab); + tetraPtr = ptr; + + nbElem = tab[0]; + int nbNodes = tab[1]; + + for (int i=0; i < 4*nbElem; i++) + strtol(ptr, &ptr, 10); + + for (int iNode=1; iNode <= nbNodes; iNode++) + for (int iCoor=0; iCoor < 3; iCoor++) + strtod(ptr, &ptr); + + + // Reading the number of triangles which corresponds to the number of sub-domains + int nbTriangle = strtol(ptr, &ptr, 10); +#else + // The keyword does not exist yet => to update when it is created + int nbTriangle = GmfStatKwd(InpMsh, GmfSubdomain); + int id_tri[3]; +#endif + + tabID = new int[nbTriangle]; + for (int i=0; i < nbTriangle; i++) { + tabID[i] = 0; + int nodeId1, nodeId2, nodeId3; + // find the solid corresponding to GHS3D sub-domain following + // the technique proposed in GHS3D manual in chapter + // "B.4 Subdomain (sub-region) assignment" +#ifndef GMF_HAS_SUBDOMAIN_INFO + nodeId1 = strtol(ptr, &ptr, 10); + nodeId2 = strtol(ptr, &ptr, 10); + nodeId3 = strtol(ptr, &ptr, 10); +#else + // The keyword does not exist yet => to update when it is created + GmfGetLin(InpMsh, GmfSubdomain, &id_tri[0], &id_tri[1], &id_tri[2]); + nodeId1 = id_tri[0]; + nodeId2 = id_tri[1]; + nodeId3 = id_tri[2]; +#endif + if ( nbTriangle > 1 ) { + // get the nodes indices + const SMDS_MeshNode* n1 = theGhs3dIdToNodeMap[ nodeId1 ]; + const SMDS_MeshNode* n2 = theGhs3dIdToNodeMap[ nodeId2 ]; + const SMDS_MeshNode* n3 = theGhs3dIdToNodeMap[ nodeId3 ]; + try { + OCC_CATCH_SIGNALS; + tabID[i] = findShapeID( theMesh, n1, n2, n3, toMeshHoles ); + // -- 0020330: Pb with ghs3d as a submesh + // check that found shape is to be meshed + if ( tabID[i] > 0 ) { + const TopoDS_Shape& foundShape = theMeshDS->IndexToShape( tabID[i] ); + bool isToBeMeshed = false; + for ( int iS = 0; !isToBeMeshed && iS < nbShape; ++iS ) + isToBeMeshed = foundShape.IsSame( tabShape[ iS ]); + if ( !isToBeMeshed ) + tabID[i] = HOLE_ID; + } + // END -- 0020330: Pb with ghs3d as a submesh +#ifdef _DEBUG_ + std::cout << i+1 << " subdomain: findShapeID() returns " << tabID[i] << std::endl; +#endif + } + catch ( Standard_Failure & ex) + { +#ifdef _DEBUG_ + std::cout << i+1 << " subdomain: Exception caugt: " << ex.GetMessageString() << std::endl; +#endif + } + catch (...) { +#ifdef _DEBUG_ + std::cout << i+1 << " subdomain: unknown exception caught " << std::endl; +#endif + } + } + } + + // =========================== + // Fill the tabID array: END + // =========================== + + + tabRef[GmfVertices] = 3; + tabRef[GmfCorners] = 1; + tabRef[GmfEdges] = 2; + tabRef[GmfRidges] = 1; + tabRef[GmfTriangles] = 3; +// tabRef[GmfQuadrilaterals] = 4; + tabRef[GmfTetrahedra] = 4; +// tabRef[GmfHexahedra] = 8; + + SMDS_NodeIteratorPtr itOnGMFInputNode = theMeshDS->nodesIterator(); + while ( itOnGMFInputNode->more() ) + theMeshDS->RemoveNode( itOnGMFInputNode->next() ); + + + int nbVertices = GmfStatKwd(InpMsh, GmfVertices); + int nbCorners = max(countShape( theMeshDS, TopAbs_VERTEX ) , GmfStatKwd(InpMsh, GmfCorners)); + int nbShapeEdge = countShape( theMeshDS, TopAbs_EDGE ); + + tabCorner = new TopoDS_Shape[ nbCorners ]; + tabEdge = new TopoDS_Shape[ nbShapeEdge ]; + nodeAssigne = new int[ nbVertices + 1 ]; + GMFNodeAssigne = new int[ nbVertices + 1 ]; + GMFNode = new SMDS_MeshNode*[ nbVertices + 1 ]; + + getShape(theMeshDS, TopAbs_VERTEX, tabCorner); + getShape(theMeshDS, TopAbs_EDGE, tabEdge); + + std::map ::const_iterator it = tabRef.begin(); + for ( ; it != tabRef.end() ; ++it) + { +// int dummy; + GmfKwdCod token = it->first; + nbRef = it->second; + + nbElem = GmfStatKwd(InpMsh, token); + if (nbElem > 0) { + GmfGotoKwd(InpMsh, token); + std::cout << "Read " << nbElem; + } + else + continue; + + int id[nbElem*tabRef[token]]; + int ghs3dShapeID[nbElem]; + + if (token == GmfVertices) { + std::cout << " vertices" << std::endl; + int aGMFID; + + float VerTab_f[nbElem][3]; + double VerTab_d[nbElem][3]; + SMDS_MeshNode * aGMFNode; + + for ( int iElem = 0; iElem < nbElem; iElem++ ) { + aGMFID = iElem + 1; + if (ver == GmfFloat) { + GmfGetLin(InpMsh, token, &VerTab_f[nbElem][0], &VerTab_f[nbElem][1], &VerTab_f[nbElem][2], &ghs3dShapeID[iElem]); + aGMFNode = theMeshDS->AddNode(VerTab_f[nbElem][0], VerTab_f[nbElem][1], VerTab_f[nbElem][2]); + } + else { + GmfGetLin(InpMsh, token, &VerTab_d[nbElem][0], &VerTab_d[nbElem][1], &VerTab_d[nbElem][2], &ghs3dShapeID[iElem]); + aGMFNode = theMeshDS->AddNode(VerTab_d[nbElem][0], VerTab_d[nbElem][1], VerTab_d[nbElem][2]); + } + GMFNode[ aGMFID ] = aGMFNode; + nodeAssigne[ aGMFID ] = 0; + GMFNodeAssigne[ aGMFID ] = 0; + } + } + else if (token == GmfCorners && nbElem > 0) { + std::cout << " corners" << std::endl; + for ( int iElem = 0; iElem < nbElem; iElem++ ) + GmfGetLin(InpMsh, token, &id[iElem*tabRef[token]]); + } + else if (token == GmfRidges && nbElem > 0) { + std::cout << " ridges" << std::endl; + for ( int iElem = 0; iElem < nbElem; iElem++ ) + GmfGetLin(InpMsh, token, &id[iElem*tabRef[token]]); + } + else if (token == GmfEdges && nbElem > 0) { + std::cout << " edges" << std::endl; + for ( int iElem = 0; iElem < nbElem; iElem++ ) + GmfGetLin(InpMsh, token, &id[iElem*tabRef[token]], &id[iElem*tabRef[token]+1], &ghs3dShapeID[iElem]); + } + else if (token == GmfTriangles && nbElem > 0) { + std::cout << " triangles" << std::endl; + for ( int iElem = 0; iElem < nbElem; iElem++ ) + GmfGetLin(InpMsh, token, &id[iElem*tabRef[token]], &id[iElem*tabRef[token]+1], &id[iElem*tabRef[token]+2], &ghs3dShapeID[iElem]); + } +// else if (token == GmfQuadrilaterals && nbElem > 0) { +// std::cout << " Quadrilaterals" << std::endl; +// for ( int iElem = 0; iElem < nbElem; iElem++ ) +// GmfGetLin(InpMsh, token, &id[iElem*tabRef[token]], &id[iElem*tabRef[token]+1], &id[iElem*tabRef[token]+2], &id[iElem*tabRef[token]+3], &ghs3dShapeID[iElem]); +// } + else if (token == GmfTetrahedra && nbElem > 0) { + std::cout << " Tetrahedra" << std::endl; + for ( int iElem = 0; iElem < nbElem; iElem++ ) + GmfGetLin(InpMsh, token, + &id[iElem*tabRef[token]], + &id[iElem*tabRef[token]+1], + &id[iElem*tabRef[token]+2], + &id[iElem*tabRef[token]+3], + &ghs3dShapeID[iElem]); + } +// else if (token == GmfHexahedra && nbElem > 0) { +// std::cout << " Hexahedra" << std::endl; +// for ( int iElem = 0; iElem < nbElem; iElem++ ) +// GmfGetLin(InpMsh, token, &id[iElem*tabRef[token]], &id[iElem*tabRef[token]+1], &id[iElem*tabRef[token]+2], &id[iElem*tabRef[token]+3], +// &id[iElem*tabRef[token]+4], &id[iElem*tabRef[token]+5], &id[iElem*tabRef[token]+6], &id[iElem*tabRef[token]+7], &ghs3dShapeID[iElem]); +// } + + switch (token) { + case GmfCorners: + case GmfRidges: + case GmfEdges: + case GmfTriangles: +// case GmfQuadrilaterals: + case GmfTetrahedra: +// case GmfHexahedra: + { + int nodeDim, shapeID, *nodeID; + SMDS_MeshNode** node; +// std::vector< SMDS_MeshNode* > enfNode( nbRef ); + SMDS_MeshElement * aGMFElement; + + node = new SMDS_MeshNode*[nbRef]; + nodeID = new int[ nbRef ]; + + for ( int iElem = 0; iElem < nbElem; iElem++ ) + { + for ( int iRef = 0; iRef < nbRef; iRef++ ) + { + aGMFNodeID = id[iElem*tabRef[token]+iRef]; // read nbRef aGMFNodeID + node [ iRef ] = GMFNode[ aGMFNodeID ]; + nodeID[ iRef ] = aGMFNodeID; + } + + switch (token) + { + case GmfCorners: { + nodeDim = 1; + gp_Pnt GMFPnt ( node[0]->X(), node[0]->Y(), node[0]->Z() ); + for ( int i=0; iAddEdge( node[0], node[1] ); + int iNode = 1; + if ( GMFNodeAssigne[ nodeID[0] ] == 0 || GMFNodeAssigne[ nodeID[0] ] == 2 ) + iNode = 0; + shapeID = findEdgeID( node[iNode], theMeshDS, nbShapeEdge, tabEdge ); + break; + } + case GmfRidges: + break; + case GmfTriangles: { + nodeDim = 3; + aGMFElement = theMeshDS->AddFace( node[0], node[1], node[2]); + shapeID = -1; + break; + } +// case GmfQuadrilaterals: { +// nodeDim = 4; +// aGMFElement = theMeshDS->AddFace( node[0], node[1], node[2], node[3] ); +// shapeID = -1; +// break; +// } + case GmfTetrahedra: { + + // IN WORK + TopoDS_Shape aSolid; + // We always run GHS3D with "to mesh holes"==TRUE but we must not create + // tetras within holes depending on hypo option, + // so we first check if aTet is inside a hole and then create it + if ( nbTriangle > 1 ) { + tetraShapeID = HOLE_ID; // negative tetraShapeID means not to create tetras if !toMeshHoles + int aGhs3dShapeID = ghs3dShapeID[iElem] - IdShapeRef; + if ( tabID[ aGhs3dShapeID ] == 0 ) { + TopAbs_State state; + aSolid = findShape(node, aSolid, tabShape, tabBox, nbShape, &state); + if ( toMeshHoles || state == TopAbs_IN ) + tetraShapeID = theMeshDS->ShapeToIndex( aSolid ); + tabID[ aGhs3dShapeID ] = tetraShapeID; + } + else + tetraShapeID = tabID[ aGhs3dShapeID ]; + } + else if ( nbShape > 1 ) { + // Case where nbTriangle == 1 while nbShape == 2 encountered + // with compound of 2 boxes and "To mesh holes"==False, + // so there are no subdomains specified for each tetrahedron. + // Try to guess a solid by a node already bound to shape + tetraShapeID = 0; + for ( int i=0; i<4 && tetraShapeID==0; i++ ) { + if ( nodeAssigne[ nodeID[i] ] == 1 && + node[i]->GetPosition()->GetTypeOfPosition() == SMDS_TOP_3DSPACE && + node[i]->getshapeId() > 1 ) + { + tetraShapeID = node[i]->getshapeId(); + } + } + if ( tetraShapeID==0 ) { + aSolid = findShape(node, aSolid, tabShape, tabBox, nbShape); + tetraShapeID = theMeshDS->ShapeToIndex( aSolid ); + } + } + // set new nodes and tetrahedron onto the shape + for ( int i=0; i<4; i++ ) { + if ( nodeAssigne[ nodeID[i] ] == 0 ) { + if ( tetraShapeID != HOLE_ID ) + theMeshDS->SetNodeInVolume( node[i], tetraShapeID ); + nodeAssigne[ nodeID[i] ] = tetraShapeID; + } + } + if ( toMeshHoles || tetraShapeID != HOLE_ID ) { + aGMFElement = theMeshDS->AddVolume( node[1], node[0], node[2], node[3] ); + theMeshDS->SetMeshElementOnShape( aGMFElement, tetraShapeID ); + } + + // IN WORK + + nodeDim = 5; + break; + } +// case GmfHexahedra: { +// nodeDim = 6; +// aGMFElement = theMeshDS->AddVolume( node[0], node[3], node[2], node[1], +// node[4], node[7], node[6], node[5] ); +// break; +// } + default: continue; + } + if (token != GmfRidges) + { + for ( int i=0; iSetNodeOnVertex( node[0], aVertex ); + else if ( token == GmfEdges ) theMeshDS->SetNodeOnEdge( node[i], shapeID ); + else if ( token == GmfTriangles ) theMeshDS->SetNodeOnFace( node[i], shapeID ); + GMFNodeAssigne[ nodeID[i] ] = nodeDim; + } + } + if ( token != "Corners" ) + theMeshDS->SetMeshElementOnShape( aGMFElement, shapeID ); + } + } // for + + if ( !toMeshHoles ) { + map ::iterator itOnNode = theGhs3dIdToNodeMap.find( nbVertices-(nbEnforcedVertices+nbEnforcedNodes) ); + for ( ; itOnNode != theGhs3dIdToNodeMap.end(); ++itOnNode) { + if ( nodeAssigne[ itOnNode->first ] == HOLE_ID ) + theMeshDS->RemoveFreeNode( itOnNode->second, 0 ); + } + } + + delete [] node; + delete [] nodeID; + break; + } // case GmfTetrahedra + } // switch(token) + } // for + cout << std::endl; + +#ifndef GMF_HAS_SUBDOMAIN_INFO +#ifdef WNT + UnmapViewOfFile(mapPtr); + CloseHandle(hMapObject); + CloseHandle(fd); +#else + munmap(mapPtr, length); #endif -//======================================================================= -//function : countShape -//purpose : -//======================================================================= + close(fileOpen); +#endif + + delete [] tabID; + delete [] tabCorner; + delete [] tabEdge; + delete [] nodeAssigne; + delete [] GMFNodeAssigne; + delete [] GMFNode; + + return true; +} -// template < class Mesh, class Shape > -// static int countShape( Mesh* mesh, Shape shape ) { -// TopExp_Explorer expShape ( mesh->ShapeToMesh(), shape ); -// int nbShape = 0; -// for ( ; expShape.More(); expShape.Next() ) { -// nbShape++; -// } -// return nbShape; -// } -#if GHS3D_VERSION >= 42 //======================================================================= //function : readGMFFile //purpose : @@ -278,15 +976,11 @@ static bool readGMFFile(const char* theFile, SMESH_MesherHelper* theHelper, // Read generated elements and nodes // --------------------------------- -// std::string token; int nbElem = 0, nbRef = 0; int aGMFNodeID = 0, shapeID; int *nodeAssigne; - std::map tabRef; SMDS_MeshNode** GMFNode; - -// int nbEnfTri = theEnforcedTriangles.size(); -// int nbEnfQuad = theEnforcedQuadrangles.size(); + std::map tabRef; tabRef[GmfVertices] = 3; tabRef[GmfCorners] = 1; @@ -316,7 +1010,6 @@ static bool readGMFFile(const char* theFile, SMESH_MesherHelper* theHelper, GmfKwdCod token = it->first; nbRef = it->second; - nbElem = GmfStatKwd(InpMsh, token); if (nbElem > 0) { GmfGotoKwd(InpMsh, token); @@ -337,37 +1030,16 @@ static bool readGMFFile(const char* theFile, SMESH_MesherHelper* theHelper, for ( int iElem = 0; iElem < nbElem; iElem++ ) { aGMFID = iElem + 1; -// TIDSortedNodeSet theEnforcedNodesCopy = theEnforcedNodes; -// SMESH_MeshEditor::TListOfListOfNodes aGroupsOfNodes; if (ver == GmfFloat) { GmfGetLin(InpMsh, token, &VerTab_f[nbElem][0], &VerTab_f[nbElem][1], &VerTab_f[nbElem][2], &dummy); aGMFNode = theMesh->AddNode(VerTab_f[nbElem][0], VerTab_f[nbElem][1], VerTab_f[nbElem][2]); -// theEnforcedNodesCopy.insert(aGMFNode); -// if (!theEnforcedNodesCopy.insert(aGMFNode).second) -// std::cout << "No added into theEnforcedNodesCopy: " << aGMFNode; -// SMESH_OctreeNode::FindCoincidentNodes ( theEnforcedNodesCopy, &aGroupsOfNodes, 1e-5); } else { GmfGetLin(InpMsh, token, &VerTab_d[nbElem][0], &VerTab_d[nbElem][1], &VerTab_d[nbElem][2], &dummy); aGMFNode = theMesh->AddNode(VerTab_d[nbElem][0], VerTab_d[nbElem][1], VerTab_d[nbElem][2]); -// theEnforcedNodesCopy.insert(aGMFNode); -// if (!theEnforcedNodesCopy.insert(aGMFNode).second) -// std::cout << "No added into theEnforcedNodesCopy: " << aGMFNode; -// SMESH_OctreeNode::FindCoincidentNodes ( theEnforcedNodesCopy, &aGroupsOfNodes, 1e-5); } GMFNode[ aGMFID ] = aGMFNode; nodeAssigne[ aGMFID ] = 0; -// if (aGroupsOfNodes.size()) { -// std::cout << "Coincident node found when adding " << aGMFNode; -// SMESH_MeshEditor::TListOfListOfNodes::iterator grIt = aGroupsOfNodes.begin(); -// for ( ; grIt != aGroupsOfNodes.end(); grIt++) { -// list& nodes = *grIt; -// list::iterator nIt = nodes.begin(); -// for ( ; nIt != nodes.end(); nIt++ ) -// std::cout << *nIt; -// } -//// theMesh->RemoveNode(aGMFNode); -// } } } else if (token == GmfCorners && nbElem > 0) { @@ -406,6 +1078,7 @@ static bool readGMFFile(const char* theFile, SMESH_MesherHelper* theHelper, GmfGetLin(InpMsh, token, &id[iElem*tabRef[token]], &id[iElem*tabRef[token]+1], &id[iElem*tabRef[token]+2], &id[iElem*tabRef[token]+3], &id[iElem*tabRef[token]+4], &id[iElem*tabRef[token]+5], &id[iElem*tabRef[token]+6], &id[iElem*tabRef[token]+7], &dummy); } + std::cout << std::endl; switch (token) { case GmfCorners: @@ -434,32 +1107,10 @@ static bool readGMFFile(const char* theFile, SMESH_MesherHelper* theHelper, theHelper->AddEdge( node[0], node[1] ); break; case GmfTriangles: { theMesh->AddFace( node[0], node[1], node[2]); - // Enforced triangles -// for ( int iEnfElem = nbElem; iEnfElem < nbElem+nbEnfTri; iEnfElem++ ) -// { -// for ( int iRef = 0; iRef < nbRef; iRef++ ) -// { -// aGMFNodeID = id[iEnfElem*tabRef[token]+iRef]; // read nbRef aGMFNodeID -// enfNode [ iRef ] = GMFNode[ aGMFNodeID ]; -// nodeAssigne[ aGMFNodeID] = 1; -// } -// theMesh->AddFace( enfNode[0], enfNode[1], enfNode[2]); -// } break; } case GmfQuadrilaterals: { theMesh->AddFace( node[0], node[1], node[2], node[3] ); - // Enforced Quadrilaterals -// for ( int iEnfElem = nbElem+nbEnfTri; iEnfElem < nbElem+nbEnfTri+nbEnfQuad; iEnfElem++ ) -// { -// for ( int iRef = 0; iRef < nbRef; iRef++ ) -// { -// aGMFNodeID = id[iEnfElem*tabRef[token]+iRef]; // read nbRef aGMFNodeID -// enfNode [ iRef ] = GMFNode[ aGMFNodeID ]; -// nodeAssigne[ aGMFNodeID] = 1; -// } -// theMesh->AddFace( enfNode[0], enfNode[1], enfNode[2], enfNode[3]); -// } break; } case GmfTetrahedra: @@ -477,7 +1128,6 @@ static bool readGMFFile(const char* theFile, SMESH_MesherHelper* theHelper, } } } - cout << std::endl; shapeID = theHelper->GetSubShapeID(); for ( int i = 0; i < nbVertices; ++i ) @@ -503,7 +1153,7 @@ static bool writeGMFFile(const char* theMeshFileName, TIDSortedElemSet & theEnforcedQuadrangles, GHS3DPlugin_Hypothesis::TEnforcedVertexValues & theEnforcedVertices) { - MESSAGE("writeGMFFile"); + MESSAGE("writeGMFFile w/o geometry"); int idx, idxRequired, idxSol; const int dummyint = 0; GHS3DPlugin_Hypothesis::TEnforcedVertexValues::const_iterator vertexIt; @@ -979,6 +1629,7 @@ static bool writeGMFFile(const char* theMeshFileName, TIDSortedElemSet & theEnforcedQuadrangles, GHS3DPlugin_Hypothesis::TEnforcedVertexValues & theEnforcedVertices) { + MESSAGE("writeGMFFile with geometry"); int idx, nbv, nbev, nben, aGhs3dID = 0; const int dummyint = 0; GHS3DPlugin_Hypothesis::TEnforcedVertexValues::const_iterator vertexIt; @@ -2152,197 +2803,6 @@ static bool writePoints (ofstream & theFile, return true; } -//================================================================================ -/*! - * \brief returns true if a triangle defined by the nodes is a temporary face on a - * side facet of pyramid and defines sub-domian inside the pyramid - */ -//================================================================================ - -static bool isTmpFace(const SMDS_MeshNode* node1, - const SMDS_MeshNode* node2, - const SMDS_MeshNode* node3) -{ - // find a pyramid sharing the 3 nodes - //const SMDS_MeshElement* pyram = 0; - SMDS_ElemIteratorPtr vIt1 = node1->GetInverseElementIterator(SMDSAbs_Volume); - while ( vIt1->more() ) - { - const SMDS_MeshElement* pyram = vIt1->next(); - if ( pyram->NbCornerNodes() != 5 ) continue; - int i2, i3; - if ( (i2 = pyram->GetNodeIndex( node2 )) >= 0 && - (i3 = pyram->GetNodeIndex( node3 )) >= 0 ) - { - // Triangle defines sub-domian inside the pyramid if it's - // normal points out of the pyram - - // make i2 and i3 hold indices of base nodes of the pyram while - // keeping the nodes order in the triangle - const int iApex = 4; - if ( i2 == iApex ) - i2 = i3, i3 = pyram->GetNodeIndex( node1 ); - else if ( i3 == iApex ) - i3 = i2, i2 = pyram->GetNodeIndex( node1 ); - - int i3base = (i2+1) % 4; // next index after i2 within the pyramid base - return ( i3base != i3 ); - } - } - return false; -} - -//======================================================================= -//function : findShapeID -//purpose : find the solid corresponding to GHS3D sub-domain following -// the technique proposed in GHS3D manual (available within -// ghs3d installation) in chapter "B.4 Subdomain (sub-region) assignment". -// In brief: normal of the triangle defined by the given nodes -// points out of the domain it is associated to -//======================================================================= - -static int findShapeID(SMESH_Mesh& mesh, - const SMDS_MeshNode* node1, - const SMDS_MeshNode* node2, - const SMDS_MeshNode* node3, - const bool toMeshHoles) -{ - const int invalidID = 0; - SMESHDS_Mesh* meshDS = mesh.GetMeshDS(); - - // face the nodes belong to - const SMDS_MeshElement * face = meshDS->FindFace(node1,node2,node3); - if ( !face ) - return isTmpFace(node1, node2, node3) ? HOLE_ID : invalidID; -#ifdef _DEBUG_ - std::cout << "bnd face " << face->GetID() << " - "; -#endif - // geom face the face assigned to - SMESH_MeshEditor editor(&mesh); - int geomFaceID = editor.FindShape( face ); - if ( !geomFaceID ) - return isTmpFace(node1, node2, node3) ? HOLE_ID : invalidID; - TopoDS_Shape shape = meshDS->IndexToShape( geomFaceID ); - if ( shape.IsNull() || shape.ShapeType() != TopAbs_FACE ) - return invalidID; - TopoDS_Face geomFace = TopoDS::Face( shape ); - - // solids bounded by geom face - TopTools_IndexedMapOfShape solids, shells; - TopTools_ListIteratorOfListOfShape ansIt = mesh.GetAncestors(geomFace); - for ( ; ansIt.More(); ansIt.Next() ) { - switch ( ansIt.Value().ShapeType() ) { - case TopAbs_SOLID: - solids.Add( ansIt.Value() ); break; - case TopAbs_SHELL: - shells.Add( ansIt.Value() ); break; - default:; - } - } - // analyse found solids - if ( solids.Extent() == 0 || shells.Extent() == 0) - return invalidID; - - const TopoDS_Solid& solid1 = TopoDS::Solid( solids(1) ); - if ( solids.Extent() == 1 ) - { - if ( toMeshHoles ) - return meshDS->ShapeToIndex( solid1 ); - - // - Are we at a hole boundary face? - if ( shells(1).IsSame( BRepTools::OuterShell( solid1 )) ) - { // - No, but maybe a hole is bound by two shapes? Does shells(1) touches another shell? - bool touch = false; - TopExp_Explorer eExp( shells(1), TopAbs_EDGE ); - // check if any edge of shells(1) belongs to another shell - for ( ; eExp.More() && !touch; eExp.Next() ) { - ansIt = mesh.GetAncestors( eExp.Current() ); - for ( ; ansIt.More() && !touch; ansIt.Next() ) { - if ( ansIt.Value().ShapeType() == TopAbs_SHELL ) - touch = ( !ansIt.Value().IsSame( shells(1) )); - } - } - if (!touch) - return meshDS->ShapeToIndex( solid1 ); - } - } - // find orientation of geom face within the first solid - TopExp_Explorer fExp( solid1, TopAbs_FACE ); - for ( ; fExp.More(); fExp.Next() ) - if ( geomFace.IsSame( fExp.Current() )) { - geomFace = TopoDS::Face( fExp.Current() ); - break; - } - if ( !fExp.More() ) - return invalidID; // face not found - - // normale to triangle - gp_Pnt node1Pnt ( node1->X(), node1->Y(), node1->Z() ); - gp_Pnt node2Pnt ( node2->X(), node2->Y(), node2->Z() ); - gp_Pnt node3Pnt ( node3->X(), node3->Y(), node3->Z() ); - gp_Vec vec12( node1Pnt, node2Pnt ); - gp_Vec vec13( node1Pnt, node3Pnt ); - gp_Vec meshNormal = vec12 ^ vec13; - if ( meshNormal.SquareMagnitude() < DBL_MIN ) - return invalidID; - - // get normale to geomFace at any node - bool geomNormalOK = false; - gp_Vec geomNormal; - const SMDS_MeshNode* nodes[3] = { node1, node2, node3 }; - SMESH_MesherHelper helper( mesh ); helper.SetSubShape( geomFace ); - for ( int i = 0; !geomNormalOK && i < 3; ++i ) - { - // find UV of i-th node on geomFace - const SMDS_MeshNode* nNotOnSeamEdge = 0; - if ( helper.IsSeamShape( nodes[i]->getshapeId() )) { - if ( helper.IsSeamShape( nodes[(i+1)%3]->getshapeId() )) - nNotOnSeamEdge = nodes[(i+2)%3]; - else - nNotOnSeamEdge = nodes[(i+1)%3]; - } - bool uvOK; - gp_XY uv = helper.GetNodeUV( geomFace, nodes[i], nNotOnSeamEdge, &uvOK ); - // check that uv is correct - if (uvOK) { - double tol = 1e-6; - TopoDS_Shape nodeShape = helper.GetSubShapeByNode( nodes[i], meshDS ); - if ( !nodeShape.IsNull() ) - switch ( nodeShape.ShapeType() ) - { - case TopAbs_FACE: tol = BRep_Tool::Tolerance( TopoDS::Face( nodeShape )); break; - case TopAbs_EDGE: tol = BRep_Tool::Tolerance( TopoDS::Edge( nodeShape )); break; - case TopAbs_VERTEX: tol = BRep_Tool::Tolerance( TopoDS::Vertex( nodeShape )); break; - default:; - } - gp_Pnt nodePnt ( nodes[i]->X(), nodes[i]->Y(), nodes[i]->Z() ); - BRepAdaptor_Surface surface( geomFace ); - uvOK = ( nodePnt.Distance( surface.Value( uv.X(), uv.Y() )) < 2 * tol ); - if ( uvOK ) { - // normale to geomFace at UV - gp_Vec du, dv; - surface.D1( uv.X(), uv.Y(), nodePnt, du, dv ); - geomNormal = du ^ dv; - if ( geomFace.Orientation() == TopAbs_REVERSED ) - geomNormal.Reverse(); - geomNormalOK = ( geomNormal.SquareMagnitude() > DBL_MIN * 1e3 ); - } - } - } - if ( !geomNormalOK) - return invalidID; - - // compare normals - bool isReverse = ( meshNormal * geomNormal ) < 0; - if ( !isReverse ) - return meshDS->ShapeToIndex( solid1 ); - - if ( solids.Extent() == 1 ) - return HOLE_ID; // we are inside a hole - else - return meshDS->ShapeToIndex( solids(2) ); -} - //======================================================================= //function : readResultFile //purpose : @@ -2386,13 +2846,13 @@ static bool readResultFile(const int fileOpen, int *tab, *tabID, *nodeID, *nodeAssigne; double *coord; - const SMDS_MeshNode **node; + SMDS_MeshNode **node; tab = new int[3]; //tabID = new int[nbShape]; nodeID = new int[4]; coord = new double[3]; - node = new const SMDS_MeshNode*[4]; + node = new SMDS_MeshNode*[4]; TopoDS_Shape aSolid; SMDS_MeshNode * aNewNode; @@ -2809,7 +3269,8 @@ bool GHS3DPlugin_GHS3D::Compute(SMESH_Mesh& theMesh, TCollection_AsciiString aGenericName = (char*) GHS3DPlugin_Hypothesis::GetFileName(_hyp).c_str(); - TCollection_AsciiString aLogFileName, aResultFileName; + TCollection_AsciiString aResultFileName; + TCollection_AsciiString aLogFileName = aGenericName + ".log"; // log #if GHS3D_VERSION < 42 TCollection_AsciiString aFacesFileName, aPointsFileName; TCollection_AsciiString aBadResFileName, aBbResFileName; @@ -2835,14 +3296,31 @@ bool GHS3DPlugin_GHS3D::Compute(SMESH_Mesh& theMesh, } #else TCollection_AsciiString aGMFFileName, aRequiredVerticesFileName, aSolFileName; +#ifndef GMF_HAS_SUBDOMAIN_INFO + TCollection_AsciiString aResultGMFFileName; +#endif #ifdef _DEBUG_ aGMFFileName = aGenericName + ".mesh"; // GMF mesh file +#ifndef GMF_HAS_SUBDOMAIN_INFO + // The output .mesh file does not contain yet the subdomain-info (Ghs3D 4.2) + aResultGMFFileName = aGenericName + "Vol.mesh"; // GMF mesh file + aResultFileName = aGenericName + ".noboite";// out points and volumes +#else aResultFileName = aGenericName + "Vol.mesh"; // GMF mesh file +#endif aRequiredVerticesFileName = aGenericName + "_required.mesh"; // GMF required vertices mesh file aSolFileName = aGenericName + "_required.sol"; // GMF solution file #else - aGMFFileName = aGenericName + ".meshb"; // GMF mesh file +#ifndef GMF_HAS_SUBDOMAIN_INFO + // The output .mesh file does not contain yet the subdomain-info (Ghs3D 4.2) +// aGMFFileName = aGenericName + ".mesh"; // GMF mesh file + aResultGMFFileName = aGenericName + "Vol.meshb"; // GMF mesh file + aResultFileName = aGenericName + ".noboite";// out points and volumes +#else +// aGMFFileName = aGenericName + ".meshb"; // GMF mesh file aResultFileName = aGenericName + "Vol.meshb"; // GMF mesh file +#endif + aGMFFileName = aGenericName + ".meshb"; // GMF mesh file aRequiredVerticesFileName = aGenericName + "_required.meshb"; // GMF required vertices mesh file aSolFileName = aGenericName + ".solb"; // GMF solution file #endif @@ -2858,6 +3336,9 @@ bool GHS3DPlugin_GHS3D::Compute(SMESH_Mesh& theMesh, GHS3DPlugin_Hypothesis::TID2SizeMap nodeIDToSizeMap = GHS3DPlugin_Hypothesis::GetNodeIDToSizeMap(_hyp); // GHS3DPlugin_Hypothesis::TID2SizeMap elemIDToSizeMap = GHS3DPlugin_Hypothesis::GetElementIDToSizeMap(_hyp); + int nbEnforcedVertices = enforcedVertices.size(); + int nbEnforcedNodes = enforcedNodes.size(); + SMESH_MesherHelper helper( theMesh ); helper.SetSubShape( theShape ); @@ -2898,8 +3379,6 @@ bool GHS3DPlugin_GHS3D::Compute(SMESH_Mesh& theMesh, writeFaces ( aFacesFile, *proxyMesh, theShape, aSmdsToGhs3dIdMap, anEnforcedNodeIdToGhs3dIdMap, enforcedEdges, enforcedTriangles, enforcedQuadrangles)); - int nbEnforcedVertices = enforcedVertices.size(); - int nbEnforcedNodes = enforcedNodes.size(); #else Ok = writeGMFFile(aGMFFileName.ToCString(), aRequiredVerticesFileName.ToCString(), aSolFileName.ToCString(), helper, *proxyMesh, @@ -2936,6 +3415,10 @@ bool GHS3DPlugin_GHS3D::Compute(SMESH_Mesh& theMesh, #if GHS3D_VERSION < 42 removeFile( aFacesFileName ); removeFile( aPointsFileName ); +#else + removeFile( aGMFFileName ); + removeFile( aRequiredVerticesFileName ); + removeFile( aSolFileName ); #endif removeFile( aSmdsToGhs3dIdMapFileName ); } @@ -2948,12 +3431,15 @@ bool GHS3DPlugin_GHS3D::Compute(SMESH_Mesh& theMesh, // ----------------- TCollection_AsciiString cmd = TCollection_AsciiString((char*)GHS3DPlugin_Hypothesis::CommandToRun( _hyp ).c_str() ); -#if GHS3D_VERSION < 42 + // The output .mesh file does not contain yet the subdomain-info (Ghs3D 4.2) +// #if GHS3D_VERSION < 42 cmd += TCollection_AsciiString(" -f ") + aGenericName; // file to read -#else - cmd += TCollection_AsciiString(" --in ") + aGenericName; +// #else +#if GHS3D_VERSION >= 42 + cmd += TCollection_AsciiString(" -IM "); +// cmd += TCollection_AsciiString(" --in ") + aGenericName; // cmd += TCollection_AsciiString(" --required_vertices ") + aRequiredVerticesFileName; - cmd += TCollection_AsciiString(" --out ") + aGenericName; +// cmd += TCollection_AsciiString(" --out ") + aGenericName; #endif cmd += TCollection_AsciiString(" -Om 1>" ) + aLogFileName; // dump into file @@ -2970,6 +3456,7 @@ bool GHS3DPlugin_GHS3D::Compute(SMESH_Mesh& theMesh, // read a result // -------------- + bool toMeshHoles = _hyp ? _hyp->GetToMeshHoles(true) : GHS3DPlugin_Hypothesis::DefaultMeshHoles(); #if GHS3D_VERSION < 42 // Mapping the result file @@ -2982,8 +3469,6 @@ bool GHS3DPlugin_GHS3D::Compute(SMESH_Mesh& theMesh, Ok = false; } else { - bool toMeshHoles = - _hyp ? _hyp->GetToMeshHoles(true) : GHS3DPlugin_Hypothesis::DefaultMeshHoles(); Ok = readResultFile( fileOpen, #ifdef WNT aResultFileName.ToCString(), @@ -2994,8 +3479,30 @@ bool GHS3DPlugin_GHS3D::Compute(SMESH_Mesh& theMesh, enforcedEdges, enforcedTriangles, enforcedQuadrangles ); } #else - // TODO -// Ok = readGMFFile(aResultFileName.ToCString(), theMesh, enforcedNodesFromEnforcedElem, enforcedTriangles, enforcedQuadrangles); +#ifndef GMF_HAS_SUBDOMAIN_INFO + // The output .mesh file does not contain yet the subdomain-info (Ghs3D 4.2) + + int fileOpen = open( aResultFileName.ToCString(), O_RDONLY); + if ( fileOpen < 0 ) { + std::cout << std::endl; + std::cout << "Can't open the " << aResultFileName.ToCString() << " GHS3D output file" << std::endl; + std::cout << "Log: " << aLogFileName << std::endl; + Ok = false; + } + else { +#endif + Ok = readGMFFile( +#ifndef GMF_HAS_SUBDOMAIN_INFO + fileOpen, +#endif + aGenericName.ToCString(), theMesh, + _nbShape, tabShape, tabBox, + aGhs3dIdToNodeMap, toMeshHoles, + nbEnforcedVertices, nbEnforcedNodes, + enforcedNodes, enforcedTriangles, enforcedQuadrangles); +#ifndef GMF_HAS_SUBDOMAIN_INFO + } +#endif #endif // --------------------- @@ -3030,6 +3537,8 @@ bool GHS3DPlugin_GHS3D::Compute(SMESH_Mesh& theMesh, removeFile( aBbResFileName ); #endif removeFile( aSmdsToGhs3dIdMapFileName ); + // The output .mesh file does not contain yet the subdomain-info (Ghs3D 4.2) + removeFile( aResultFileName ); } std::cout << "<" << aResultFileName.ToCString() << "> GHS3D output file "; if ( !Ok ) @@ -3196,7 +3705,8 @@ bool GHS3DPlugin_GHS3D::Compute(SMESH_Mesh& theMesh, enforcedEdges, enforcedTriangles, enforcedQuadrangles ); } #else - Ok = readGMFFile(aResultFileName.ToCString(), aHelper, enforcedNodesFromEnforcedElem, enforcedTriangles, enforcedQuadrangles); + Ok = readGMFFile(aResultFileName.ToCString(), aHelper, + enforcedNodesFromEnforcedElem, enforcedTriangles, enforcedQuadrangles); #endif // --------------------- diff --git a/src/GHS3DPlugin/GHS3DPlugin_GHS3D.hxx b/src/GHS3DPlugin/GHS3DPlugin_GHS3D.hxx index 3378ffb..7c8358f 100644 --- a/src/GHS3DPlugin/GHS3DPlugin_GHS3D.hxx +++ b/src/GHS3DPlugin/GHS3DPlugin_GHS3D.hxx @@ -32,7 +32,14 @@ #include #include -#define GMFVERSION 2 +extern "C" +{ + #include "libmesh5.h" +} + +#ifndef GMFVERSION +#define GMFVERSION GmfDouble +#endif #define GMFDIMENSION 3 class GHS3DPlugin_Hypothesis; diff --git a/src/GHS3DPlugin/GHS3DPlugin_Hypothesis_i.cxx b/src/GHS3DPlugin/GHS3DPlugin_Hypothesis_i.cxx index f0882b6..63952ba 100644 --- a/src/GHS3DPlugin/GHS3DPlugin_Hypothesis_i.cxx +++ b/src/GHS3DPlugin/GHS3DPlugin_Hypothesis_i.cxx @@ -482,7 +482,7 @@ void GHS3DPlugin_Hypothesis_i::SetEnforcedMesh(SMESH::SMESH_IDSource_ptr theSour ExDescription.text = "Bad version of GHS3D. It must >= 4.2."; ExDescription.type = SALOME::BAD_PARAM; ExDescription.sourceFile = "GHS3DPlugin_Hypothesis::SetEnforcedMesh(theSource, theType)"; - ExDescription.lineNumber = 445; + ExDescription.lineNumber = 463; throw SALOME::SALOME_Exception(ExDescription); #endif }