From b0f7672f93f86517dcbc5db349794dc1d1bc515b Mon Sep 17 00:00:00 2001 From: mkr Date: Mon, 24 Mar 2008 10:45:10 +0000 Subject: [PATCH] Merge from BR_Dev_For_4_0. --- build_configure | 28 +- configure.ac | 9 +- idl/Makefile.am | 1 + resources/GHS3DPlugin.xml | 1 + src/GHS3DPlugin_GHS3D.cxx | 1013 ++++++++++++++++++++++++++++--------- src/GHS3DPlugin_GHS3D.hxx | 11 +- 6 files changed, 800 insertions(+), 263 deletions(-) diff --git a/build_configure b/build_configure index 711ffc9..5c6eb44 100755 --- a/build_configure +++ b/build_configure @@ -55,22 +55,22 @@ cd ${CONF_DIR} ABS_CONF_DIR=`pwd` mkdir -p salome_adm/unix/config_files -cp -f ${KERNEL_ROOT_DIR}/salome_adm/unix/config_files/* salome_adm/unix/config_files -cp -f ${KERNEL_ROOT_DIR}/salome_adm/unix/pythonbe.py salome_adm/unix +#cp -f ${KERNEL_ROOT_DIR}/salome_adm/unix/config_files/* salome_adm/unix/config_files +#cp -f ${KERNEL_ROOT_DIR}/salome_adm/unix/pythonbe.py salome_adm/unix cp -f ${KERNEL_ROOT_DIR}/salome_adm/unix/SALOMEconfig.h.in salome_adm/unix -cp -f ${GUI_ROOT_DIR}/adm_local/unix/config_files/* salome_adm/unix/config_files -cp -f ${GEOM_ROOT_DIR}/adm_local/unix/config_files/* salome_adm/unix/config_files -cp -f ${SMESH_ROOT_DIR}/adm_local/unix/config_files/* salome_adm/unix/config_files +#cp -f ${GUI_ROOT_DIR}/adm_local/unix/config_files/* salome_adm/unix/config_files +#cp -f ${GEOM_ROOT_DIR}/adm_local/unix/config_files/* salome_adm/unix/config_files +#cp -f ${SMESH_ROOT_DIR}/adm_local/unix/config_files/* salome_adm/unix/config_files # remove KERNEL deprecated configure files -for deprecated in ac_cc_warnings.m4 ac_cxx_partial_specialization.m4 \ - check_mico.m4 config.guess ltmain.sh ac_cxx_bool.m4 ltconfig ac_cxx_typename.m4 \ - check_pthreads.m4 config.sub libtool.m4 ac_cxx_mutable.m4 missing - do - rm -f salome_adm/unix/config_files/${deprecated} - done +#for deprecated in ac_cc_warnings.m4 ac_cxx_partial_specialization.m4 \ +# check_mico.m4 config.guess ltmain.sh ac_cxx_bool.m4 ltconfig ac_cxx_typename.m4 \ +# check_pthreads.m4 config.sub libtool.m4 ac_cxx_mutable.m4 missing +# do +# rm -f salome_adm/unix/config_files/${deprecated} +# done # ____________________________________________________________________ @@ -82,7 +82,11 @@ for deprecated in ac_cc_warnings.m4 ac_cxx_partial_specialization.m4 \ # autom4te.cache (directory) echo "====================================================== aclocal" -aclocal -I adm_local/unix/config_files -I salome_adm/unix/config_files || exit 1 +aclocal -I adm_local/unix/config_files \ + -I ${KERNEL_ROOT_DIR}/salome_adm/unix/config_files \ + -I ${GUI_ROOT_DIR}/adm_local/unix/config_files \ + -I ${GEOM_ROOT_DIR}/adm_local/unix/config_files \ + -I ${SMESH_ROOT_DIR}/adm_local/unix/config_files || exit 1 # ____________________________________________________________________ # libtoolize creates some configuration files (ltmain.sh, diff --git a/configure.ac b/configure.ac index bcf6c35..0a2efd7 100644 --- a/configure.ac +++ b/configure.ac @@ -15,18 +15,13 @@ # Created from configure.in.base # -AC_INIT([Salome2 Project GHS3DPLUGIN module], [4.0.0], [gboulant@CS], [salome]) +AC_INIT([Salome2 Project GHS3DPLUGIN module],[4.1.1], [webmaster.salome@opencascade.com], [salome]) AC_CONFIG_AUX_DIR(salome_adm/unix/config_files) AC_CANONICAL_HOST AC_CANONICAL_TARGET AM_INIT_AUTOMAKE -PACKAGE=salome -AC_SUBST(PACKAGE) - -VERSION=4.0.0 -XVERSION=0x040000 -AC_SUBST(VERSION) +XVERSION=`echo $VERSION | awk -F. '{printf("0x%02x%02x%02x",$1,$2,$3)}'` AC_SUBST(XVERSION) # set up MODULE_NAME variable for dynamic construction of directories (resources, etc.) diff --git a/idl/Makefile.am b/idl/Makefile.am index 0f3636c..0f0f709 100644 --- a/idl/Makefile.am +++ b/idl/Makefile.am @@ -41,6 +41,7 @@ lib_LTLIBRARIES = libSalomeIDLGHS3DPLUGIN.la nodist_libSalomeIDLGHS3DPLUGIN_la_SOURCES = \ GHS3DPlugin_AlgorithmSK.cc \ GHS3DPlugin_AlgorithmDynSK.cc +GHS3DPlugin_AlgorithmDynSK.cc: GHS3DPlugin_AlgorithmSK.cc # header files must be exported: other modules have to use this library nodist_salomeinclude_HEADERS= $(BASEIDL_FILES:%.idl=%.hh) diff --git a/resources/GHS3DPlugin.xml b/resources/GHS3DPlugin.xml index 6c33578..16ea42c 100644 --- a/resources/GHS3DPlugin.xml +++ b/resources/GHS3DPlugin.xml @@ -14,6 +14,7 @@ label-id="Tetrahedron (GHS3D)" icon-id="mesh_algo_tetra.png" input="TRIA,QUAD" + need-geom="false" dim="3"/> diff --git a/src/GHS3DPlugin_GHS3D.cxx b/src/GHS3DPlugin_GHS3D.cxx index d4fc99e..866c3fc 100644 --- a/src/GHS3DPlugin_GHS3D.cxx +++ b/src/GHS3DPlugin_GHS3D.cxx @@ -30,10 +30,12 @@ using namespace std; #include "SMESH_Gen.hxx" #include "SMESH_Mesh.hxx" #include "SMESH_Comment.hxx" +#include "SMESH_MesherHelper.hxx" #include "SMDS_MeshElement.hxx" #include "SMDS_MeshNode.hxx" +#include #include #include @@ -54,6 +56,8 @@ using namespace std; #include #include +#define castToNode(n) static_cast( n ); + #ifdef _DEBUG_ #define DUMP(txt) \ // cout << txt @@ -83,6 +87,7 @@ GHS3DPlugin_GHS3D::GHS3DPlugin_GHS3D(int hypId, int studyId, SMESH_Gen* gen) MESSAGE("GHS3DPlugin_GHS3D::GHS3DPlugin_GHS3D"); _name = "GHS3D_3D"; _shapeType = (1 << TopAbs_SHELL) | (1 << TopAbs_SOLID);// 1 bit /shape type + _onlyUnaryInput = false; // Compute() will be called on a compound of solids _iShape=0; _nbShape=0; } @@ -113,6 +118,88 @@ bool GHS3DPlugin_GHS3D::CheckHypothesis ( SMESH_Mesh& a return true; } +//======================================================================= +//function : findShape +//purpose : +//======================================================================= + +static TopoDS_Shape findShape(const SMDS_MeshNode *aNode[], + TopoDS_Shape aShape, + const TopoDS_Shape shape[], + double** box, + const int nShape) { + double *pntCoor; + int iShape, nbNode = 4; + + pntCoor = new double[3]; + for ( int i=0; i<3; i++ ) { + pntCoor[i] = 0; + for ( int j=0; jX(); + if ( i == 1) pntCoor[i] += aNode[j]->Y(); + if ( i == 2) pntCoor[i] += aNode[j]->Z(); + } + pntCoor[i] /= nbNode; + } + + gp_Pnt aPnt(pntCoor[0], pntCoor[1], pntCoor[2]); + BRepClass3d_SolidClassifier SC (aShape, aPnt, Precision::Confusion()); + if ( not(SC.State() == TopAbs_IN) ) { + for (iShape = 0; iShape < nShape; iShape++) { + aShape = shape[iShape]; + if ( not( pntCoor[0] < box[iShape][0] || box[iShape][1] < pntCoor[0] || + pntCoor[1] < box[iShape][2] || box[iShape][3] < pntCoor[1] || + pntCoor[2] < box[iShape][4] || box[iShape][5] < pntCoor[2]) ) { + BRepClass3d_SolidClassifier SC (aShape, aPnt, Precision::Confusion()); + if (SC.State() == TopAbs_IN) + break; + } + } + } + return aShape; +} + +//======================================================================= +//function : readMapIntLine +//purpose : +//======================================================================= + +static char* readMapIntLine(char* ptr, int tab[]) { + long int intVal; + cout << endl; + + for ( int i=0; i<17; i++ ) { + intVal = strtol(ptr, &ptr, 10); + if ( i < 3 ) + tab[i] = intVal; + } + return ptr; +} + +//======================================================================= +//function : readLine +//purpose : +//======================================================================= + +#define GHS3DPlugin_BUFLENGTH 256 +#define GHS3DPlugin_ReadLine(aPtr,aBuf,aFile,aLineNb) \ +{ aPtr = fgets( aBuf, GHS3DPlugin_BUFLENGTH - 2, aFile ); aLineNb++; DUMP(endl); } + +//======================================================================= +//function : countShape +//purpose : +//======================================================================= + +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; +} + //======================================================================= //function : writeFaces //purpose : @@ -128,46 +215,127 @@ static bool writeFaces (ofstream & theFile, // Loop from 1 to NB_ELEMS // NB_NODES NODE_NB_1 NODE_NB_2 ... (NB_NODES + 1) times: DUMMY_INT - // get all faces bound to theShape - - int nbFaces = 0; - TopoDS_Shape theShape = theMesh->ShapeToMesh(); - list< const SMDS_MeshElement* > faces; - TopExp_Explorer fExp( theShape, TopAbs_FACE ); - SMESHDS_SubMesh* sm; - SMDS_ElemIteratorPtr eIt; + int nbShape = countShape( theMesh, TopAbs_FACE ); + int *tabID; tabID = new int[nbShape]; + TopoDS_Shape *tabShape; tabShape = new TopoDS_Shape[nbShape]; + TopoDS_Shape aShape; + SMESHDS_SubMesh* theSubMesh; + const SMDS_MeshElement* aFace; const char* space = " "; const int dummyint = 0; + map::const_iterator itOnMap; + SMDS_ElemIteratorPtr itOnSubMesh, itOnSubFace; + int shapeID, nbNodes, aSmdsID; + bool idFound; + + cout << " " << theMesh->NbFaces() << " shapes of 2D dimension" << endl; + cout << endl; + + theFile << space << theMesh->NbFaces() << space << dummyint << endl; + + TopExp_Explorer expface( theMesh->ShapeToMesh(), TopAbs_FACE ); + for ( int i = 0; expface.More(); expface.Next(), i++ ) { + tabID[i] = 0; + aShape = expface.Current(); + shapeID = theMesh->ShapeToIndex( aShape ); + idFound = false; + for ( int j=0; j<=i; j++) { + if ( shapeID == tabID[j] ) { + idFound = true; + break; + } + } + if ( not idFound ) { + tabID[i] = shapeID; + tabShape[i] = aShape; + } + } + for ( int i =0; i < nbShape; i++ ) { + if ( not (tabID[i] == 0) ) { + aShape = tabShape[i]; + shapeID = tabID[i]; + theSubMesh = theMesh->MeshElements( aShape ); + itOnSubMesh = theSubMesh->GetElements(); + while ( itOnSubMesh->more() ) { + aFace = itOnSubMesh->next(); + nbNodes = aFace->NbNodes(); + + theFile << space << nbNodes; + + itOnSubFace = aFace->nodesIterator(); + while ( itOnSubFace->more() ) { + // find GHS3D ID + aSmdsID = itOnSubFace->next()->GetID(); + itOnMap = theSmdsToGhs3dIdMap.find( aSmdsID ); + ASSERT( itOnMap != theSmdsToGhs3dIdMap.end() ); + + theFile << space << (*itOnMap).second; + } + + // (NB_NODES + 1) times: DUMMY_INT + for ( int j=0; j<=nbNodes; j++) + theFile << space << dummyint; + + theFile << endl; + } + } + } + delete [] tabID; + delete [] tabShape; + + return true; +} + +//======================================================================= +//function : writeFaces +//purpose : Write Faces in case if generate 3D mesh w/o geometry +//======================================================================= + +static bool writeFaces (ofstream & theFile, + SMESHDS_Mesh * theMesh, + vector & theNodeByGhs3dId) +{ + // record structure: + // + // NB_ELEMS DUMMY_INT + // Loop from 1 to NB_ELEMS + // NB_NODES NODE_NB_1 NODE_NB_2 ... (NB_NODES + 1) times: DUMMY_INT + + + int nbFaces = 0; + list< const SMDS_MeshElement* > faces; list< const SMDS_MeshElement* >::iterator f; - map::const_iterator it; + map< const SMDS_MeshNode*,int >::iterator it; SMDS_ElemIteratorPtr nodeIt; const SMDS_MeshElement* elem; int nbNodes; - int aSmdsID; - - for ( ; fExp.More(); fExp.Next() ) { - sm = theMesh->MeshElements( fExp.Current() ); - if ( sm ) { - eIt = sm->GetElements(); - while ( eIt->more() ) { - faces.push_back( eIt->next() ); - nbFaces++; - } - } + + const char* space = " "; + const int dummyint = 0; + + //get all faces from mesh + SMDS_FaceIteratorPtr eIt = theMesh->facesIterator(); + while ( eIt->more() ) { + const SMDS_MeshElement* elem = eIt->next(); + if ( !elem ) + return false; + faces.push_back( elem ); + nbFaces++; } if ( nbFaces == 0 ) return false; - - cout << nbFaces << " triangles" << endl; + + cout << "The initial 2D mesh contains " << nbFaces << " faces and "; // NB_ELEMS DUMMY_INT theFile << space << nbFaces << space << dummyint << endl; // Loop from 1 to NB_ELEMS + map aNodeToGhs3dIdMap; f = faces.begin(); for ( ; f != faces.end(); ++f ) { @@ -181,10 +349,10 @@ static bool writeFaces (ofstream & theFile, while ( nodeIt->more() ) { // find GHS3D ID - aSmdsID = nodeIt->next()->GetID(); - it = theSmdsToGhs3dIdMap.find( aSmdsID ); - ASSERT( it != theSmdsToGhs3dIdMap.end() ); - theFile << space << (*it).second; + const SMDS_MeshNode* node = castToNode( nodeIt->next() ); + int newId = aNodeToGhs3dIdMap.size() + 1; // ghs3d ids count from 1 + it = aNodeToGhs3dIdMap.insert( make_pair( node, newId )).first; + theFile << space << it->second; } // (NB_NODES + 1) times: DUMMY_INT @@ -194,6 +362,14 @@ static bool writeFaces (ofstream & theFile, theFile << endl; } + // put nodes to theNodeByGhs3dId vector + theNodeByGhs3dId.resize( aNodeToGhs3dIdMap.size() ); + map::const_iterator n2id = aNodeToGhs3dIdMap.begin(); + for ( ; n2id != aNodeToGhs3dIdMap.end(); ++ n2id) + { + theNodeByGhs3dId[ n2id->second - 1 ] = n2id->first; // ghs3d ids count from 1 + } + return true; } @@ -226,7 +402,9 @@ static bool writePoints (ofstream & theFile, // NB_NODES theFile << space << nbNodes << endl; - cout << "The initial 2D mesh contains " << nbNodes << " nodes and "; + cout << endl; + cout << "The initial 2D mesh contains :" << endl; + cout << " " << nbNodes << " vertices" << endl; // Loop from 1 to NB_NODES @@ -251,78 +429,193 @@ static bool writePoints (ofstream & theFile, } //======================================================================= -//function : findSolid +//function : writePoints //purpose : //======================================================================= -static TopoDS_Shape findSolid(const SMDS_MeshNode *aNode[], - TopoDS_Shape aSolid, - const TopoDS_Shape shape[], - const double box[][6], - const int nShape) { +static bool writePoints (ofstream & theFile, + SMESHDS_Mesh * theMesh, + const vector & theNodeByGhs3dId) +{ + // record structure: + // + // NB_NODES + // Loop from 1 to NB_NODES + // X Y Z DUMMY_INT + + //int nbNodes = theMesh->NbNodes(); + int nbNodes = theNodeByGhs3dId.size(); + if ( nbNodes == 0 ) + return false; - Standard_Real PX, PY, PZ; - int iShape; + const char* space = " "; + const int dummyint = 0; - PX = ( aNode[0]->X() + aNode[1]->X() + aNode[2]->X() + aNode[3]->X() ) / 4.0; - PY = ( aNode[0]->Y() + aNode[1]->Y() + aNode[2]->Y() + aNode[3]->Y() ) / 4.0; - PZ = ( aNode[0]->Z() + aNode[1]->Z() + aNode[2]->Z() + aNode[3]->Z() ) / 4.0; - gp_Pnt aPnt(PX, PY, PZ); + const SMDS_MeshNode* node; - BRepClass3d_SolidClassifier SC (aSolid, aPnt, Precision::Confusion()); - if ( not(SC.State() == TopAbs_IN) ) { - for (iShape = 0; iShape < nShape; iShape++) { - aSolid = shape[iShape]; - if ( not( PX < box[iShape][0] || box[iShape][1] < PX || - PY < box[iShape][2] || box[iShape][3] < PY || - PZ < box[iShape][4] || box[iShape][5] < PZ) ) { - BRepClass3d_SolidClassifier SC (aSolid, aPnt, Precision::Confusion()); - if (SC.State() == TopAbs_IN) - break; - } - } + // NB_NODES + theFile << space << nbNodes << endl; + cout << nbNodes << " nodes" << endl; + + // Loop from 1 to NB_NODES + + vector::const_iterator nodeIt = theNodeByGhs3dId.begin(); + vector::const_iterator after = theNodeByGhs3dId.end(); + for ( ; nodeIt != after; ++nodeIt ) + { + node = *nodeIt; + + // X Y Z DUMMY_INT + theFile + << space << node->X() + << space << node->Y() + << space << node->Z() + << space << dummyint; + + theFile << endl; } - return aSolid; + + return true; } //======================================================================= -//function : readMapIntLine +//function : readResultFile //purpose : //======================================================================= -static char* readMapIntLine(char* ptr, int tab[]) { - long int intVal; - cout << endl; +static bool readResultFile(const int fileOpen, + SMESHDS_Mesh* theMeshDS, + TopoDS_Shape tabShape[], + double** tabBox, + const int nbShape, + map & theGhs3dIdToNodeMap) { - for ( int i=0; i<17; i++ ) { - intVal = strtol(ptr, &ptr, 10); - if ( i < 3 ) - tab[i] = intVal; + struct stat status; + size_t length; + + char *ptr, *mapPtr; + char *tetraPtr; + char *shapePtr; + + int fileStat; + int nbElems, nbNodes, nbInputNodes; + int nodeId, triangleId; + int nbTriangle; + int ID, shapeID, ghs3dShapeID; + int IdShapeRef = 1; + int compoundID = theMeshDS->ShapeToIndex( theMeshDS->ShapeToMesh() ); + + int *tab, *tabID, *nodeID, *nodeAssigne; + double *coord; + const 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]; + + TopoDS_Shape aSolid; + SMDS_MeshNode * aNewNode; + map ::iterator itOnNode; + SMDS_MeshElement* aTet; + + for (int i=0; i nbInputNodes ) { + nodeAssigne[ iNode+1 ] = 0; + aNewNode = theMeshDS->AddNode( coord[0],coord[1],coord[2] ); + theGhs3dIdToNodeMap.insert(make_pair( (iNode+1), aNewNode )); + } } - return ptr; -} -//======================================================================= -//function : readLine -//purpose : -//======================================================================= + // Reading the number of triangles which corresponds to the number of shapes + nbTriangle = strtol(ptr, &ptr, 10); -#define GHS3DPlugin_BUFLENGTH 256 -#define GHS3DPlugin_ReadLine(aPtr,aBuf,aFile,aLineNb) \ -{ aPtr = fgets( aBuf, GHS3DPlugin_BUFLENGTH - 2, aFile ); aLineNb++; DUMP(endl); } + for (int i=0; i < 3*nbShape; i++) + triangleId = strtol(ptr, &ptr, 10); + + shapePtr = ptr; + + // Associating the tetrahedrons to the shapes + shapeID = compoundID; + for (int iElem = 0; iElem < nbElems; iElem++) { + for (int iNode = 0; iNode < 4; iNode++) { + ID = strtol(tetraPtr, &tetraPtr, 10); + itOnNode = theGhs3dIdToNodeMap.find(ID); + node[ iNode ] = itOnNode->second; + nodeID[ iNode ] = ID; + } + aTet = theMeshDS->AddVolume( node[1], node[0], node[2], node[3] ); + if ( nbShape > 1 ) { + ghs3dShapeID = strtol(shapePtr, &shapePtr, 10) - IdShapeRef; + if ( tabID[ ghs3dShapeID ] == 0 ) { + if (iElem == 0) + aSolid = tabShape[0]; + aSolid = findShape(node, aSolid, tabShape, tabBox, nbShape); + shapeID = theMeshDS->ShapeToIndex( aSolid ); + tabID[ ghs3dShapeID ] = shapeID; + } + else + shapeID = tabID[ ghs3dShapeID ]; + } + // set new nodes and tetrahedron on to the shape + for ( int i=0; i<4; i++ ) { + if ( nodeAssigne[ nodeID[i] ] == 0 ) + theMeshDS->SetNodeInVolume( node[i], shapeID ); + } + theMeshDS->SetMeshElementOnShape( aTet, shapeID ); + if ( (iElem + 1) == nbElems ) + cout << nbElems << " tetrahedrons have been associated to " << nbShape << " shapes" << endl; + } + munmap(mapPtr, length); + close(fileOpen); + + delete [] tab; + delete [] tabID; + delete [] nodeID; + delete [] coord; + delete [] node; + return true; +} //======================================================================= //function : readResultFile //purpose : //======================================================================= -static bool readResultFile(const int fileOpen, - SMESHDS_Mesh* theMeshDS, - TopoDS_Shape tabShape[], - double tabBox[][6], - const int nShape, - map & theGhs3dIdToNodeMap) { +static bool readResultFile(const int fileOpen, + SMESHDS_Mesh* theMeshDS, + TopoDS_Shape aSolid, + vector & theNodeByGhs3dId) { struct stat status; size_t length; @@ -334,21 +627,21 @@ static bool readResultFile(const int fileOpen, int fileStat; int nbElems, nbNodes, nbInputNodes; int nodeId, triangleId; - int tab[3], tabID[nShape]; int nbTriangle; - int ID, shapeID, ghs3dShapeID; + int ID, shapeID; - double coord [3]; + int *tab; + double *coord; + const SMDS_MeshNode **node; + + tab = new int[3]; + coord = new double[3]; + node = new const SMDS_MeshNode*[4]; - TopoDS_Shape aSolid; SMDS_MeshNode * aNewNode; - const SMDS_MeshNode * node[4]; map ::iterator IdNode; SMDS_MeshElement* aTet; - for (int i=0; iShapeToIndex( aSolid ); for (int iNode=0; iNode < nbNodes; iNode++) { for (int iCoor=0; iCoor < 3; iCoor++) coord[ iCoor ] = strtod(ptr, &ptr); if ((iNode+1) > nbInputNodes) { aNewNode = theMeshDS->AddNode( coord[0],coord[1],coord[2] ); - theGhs3dIdToNodeMap.insert(make_pair( (iNode+1), aNewNode )); + theMeshDS->SetNodeInVolume( aNewNode, shapeID ); + theNodeByGhs3dId[ iNode ] = aNewNode; } } @@ -390,26 +687,21 @@ static bool readResultFile(const int fileOpen, for (int iElem = 0; iElem < nbElems; iElem++) { for (int iNode = 0; iNode < 4; iNode++) { ID = strtol(tetraPtr, &tetraPtr, 10); - IdNode = theGhs3dIdToNodeMap.find(ID); - node[ iNode ] = IdNode->second; + node[ iNode ] = theNodeByGhs3dId[ ID-1 ]; } aTet = theMeshDS->AddVolume( node[1], node[0], node[2], node[3] ); - ghs3dShapeID = strtol(shapePtr, &shapePtr, 10); - if ( tabID[ ghs3dShapeID - 1 ] == 0 ) { - if (iElem == 0) - aSolid = tabShape[0]; - aSolid = findSolid(node, aSolid, tabShape, tabBox, nbTriangle); - shapeID = theMeshDS->ShapeToIndex( aSolid ); - tabID[ ghs3dShapeID - 1] = shapeID; - } - else - shapeID = tabID[ ghs3dShapeID - 1]; + shapeID = theMeshDS->ShapeToIndex( aSolid ); theMeshDS->SetMeshElementOnShape( aTet, shapeID ); - if ( (iElem + 1) == nbElems ) - cout << nbElems << " tetrahedrons have been associated to " << nbTriangle << " shapes" << endl; } + if ( nbElems ) + cout << nbElems << " tetrahedrons have been associated to " << nbTriangle << " shapes" << endl; munmap(mapPtr, length); close(fileOpen); + + delete [] tab; + delete [] coord; + delete [] node; + return true; } @@ -443,49 +735,32 @@ static TCollection_AsciiString getTmpDir() //================================================================================ /*! - * \brief Decrease amount of memory GHS3D may use until it can allocate it - * \param nbMB - memory size to adjust - * \param aLogFileName - file for GHS3D output - * \retval bool - false if GHS3D can not run for any reason + * \brief Look for a line containing a text in a file + * \retval bool - true if the line is found */ //================================================================================ -static bool adjustMemory(int & nbMB, const TCollection_AsciiString & aLogFileName) +static bool findLineContaing(const TCollection_AsciiString& theText, + const TCollection_AsciiString& theFile, + TCollection_AsciiString & theFoundLine) { - TCollection_AsciiString cmd( "ghs3d -m " ); - cmd += nbMB; - cmd += " 1>"; - cmd += aLogFileName; - - system( cmd.ToCString() ); // run - - // analyse log file - - FILE * aLogFile = fopen( aLogFileName.ToCString(), "r" ); - if ( aLogFile ) + bool found = false; + if ( FILE * aFile = fopen( theFile.ToCString(), "r" )) { - bool memoryOK = true; char * aPtr; char aBuffer[ GHS3DPlugin_BUFLENGTH ]; int aLineNb = 0; - do { - GHS3DPlugin_ReadLine( aPtr, aBuffer, aLogFile, aLineNb ); + do { + GHS3DPlugin_ReadLine( aPtr, aBuffer, aFile, aLineNb ); if ( aPtr ) { - TCollection_AsciiString line( aPtr ); - if ( line.Search( "UNABLE TO ALLOCATE MEMORY" ) > 0 ) - memoryOK = false; + theFoundLine = aPtr; + found = theFoundLine.Search( theText ) >= 0; } - } while ( aPtr && memoryOK ); - - fclose( aLogFile ); + } while ( aPtr && !found ); - if ( !memoryOK ) { - nbMB *= 0.75; - return adjustMemory( nbMB, aLogFileName ); - } - return true; + fclose( aFile ); } - return false; + return found; } //============================================================================= @@ -500,156 +775,408 @@ bool GHS3DPlugin_GHS3D::Compute(SMESH_Mesh& theMesh, bool Ok(false); SMESHDS_Mesh* meshDS = theMesh.GetMeshDS(); - if (_iShape == 0 && _nbShape == 0) { - cout << endl; - cout << "Ghs3d execution..." << endl; - cout << endl; - - TopExp_Explorer exp (meshDS->ShapeToMesh(), TopAbs_SOLID); - for (; exp.More(); exp.Next()) - _nbShape++; + _nbShape = countShape( meshDS, TopAbs_SOLID ); // we count the number of shapes + + // create bounding box for every shape inside the compound + + int iShape = 0; + TopoDS_Shape* tabShape; + double** tabBox; + tabShape = new TopoDS_Shape[_nbShape]; + tabBox = new double*[_nbShape]; + for (int i=0; i<_nbShape; i++) + tabBox[i] = new double[6]; + Standard_Real Xmin, Ymin, Zmin, Xmax, Ymax, Zmax; + + TopExp_Explorer expBox (meshDS->ShapeToMesh(), TopAbs_SOLID); + for (; expBox.More(); expBox.Next()) { + tabShape[iShape] = expBox.Current(); + Bnd_Box BoundingBox; + BRepBndLib::Add(expBox.Current(), BoundingBox); + BoundingBox.Get(Xmin, Ymin, Zmin, Xmax, Ymax, Zmax); + tabBox[iShape][0] = Xmin; tabBox[iShape][1] = Xmax; + tabBox[iShape][2] = Ymin; tabBox[iShape][3] = Ymax; + tabBox[iShape][4] = Zmin; tabBox[iShape][5] = Zmax; + iShape++; } - _iShape++; - - if ( _iShape == _nbShape ) { - - // create bounding box for every shape - - int iShape = 0; - TopoDS_Shape tabShape[_nbShape]; - double tabBox[_nbShape][6]; - Standard_Real Xmin, Ymin, Zmin, Xmax, Ymax, Zmax; - - TopExp_Explorer expBox (meshDS->ShapeToMesh(), TopAbs_SOLID); - for (; expBox.More(); expBox.Next()) { - tabShape[iShape] = expBox.Current(); - Bnd_Box BoundingBox; - BRepBndLib::Add(expBox.Current(), BoundingBox); - BoundingBox.Get(Xmin, Ymin, Zmin, Xmax, Ymax, Zmax); - tabBox[iShape][0] = Xmin; tabBox[iShape][1] = Xmax; - tabBox[iShape][2] = Ymin; tabBox[iShape][3] = Ymax; - tabBox[iShape][4] = Zmin; tabBox[iShape][5] = Zmax; - iShape++; - } + cout << endl; + cout << "Ghs3d execution..." << endl; - // make a unique working file name - // to avoid access to the same files by eg different users + // make a unique working file name + // to avoid access to the same files by eg different users - TCollection_AsciiString aGenericName, aTmpDir = getTmpDir(); - aGenericName = aTmpDir + "GHS3D_"; + TCollection_AsciiString aGenericName, aTmpDir = getTmpDir(); + aGenericName = aTmpDir + "GHS3D_"; #ifdef WIN32 - aGenericName += GetCurrentProcessId(); + aGenericName += GetCurrentProcessId(); #else - aGenericName += getpid(); + aGenericName += getpid(); #endif - aGenericName += "_"; - aGenericName += meshDS->ShapeToIndex( theShape ); - - TCollection_AsciiString aFacesFileName, aPointsFileName, aResultFileName; - TCollection_AsciiString aBadResFileName, aBbResFileName, aLogFileName; - aFacesFileName = aGenericName + ".faces"; // in faces - aPointsFileName = aGenericName + ".points"; // in points - aResultFileName = aGenericName + ".noboite";// out points and volumes - aBadResFileName = aGenericName + ".boite"; // out bad result - aBbResFileName = aGenericName + ".bb"; // out vertex stepsize - aLogFileName = aGenericName + ".log"; // log - - // ----------------- - // make input files - // ----------------- - - ofstream aFacesFile ( aFacesFileName.ToCString() , ios::out); - ofstream aPointsFile ( aPointsFileName.ToCString() , ios::out); - // bool Ok = - Ok = + aGenericName += "_"; + aGenericName += meshDS->ShapeToIndex( theShape ); + + TCollection_AsciiString aFacesFileName, aPointsFileName, aResultFileName; + TCollection_AsciiString aBadResFileName, aBbResFileName, aLogFileName; + aFacesFileName = aGenericName + ".faces"; // in faces + aPointsFileName = aGenericName + ".points"; // in points + aResultFileName = aGenericName + ".noboite";// out points and volumes + aBadResFileName = aGenericName + ".boite"; // out bad result + aBbResFileName = aGenericName + ".bb"; // out vertex stepsize + aLogFileName = aGenericName + ".log"; // log + + // ----------------- + // make input files + // ----------------- + + ofstream aFacesFile ( aFacesFileName.ToCString() , ios::out); + ofstream aPointsFile ( aPointsFileName.ToCString() , ios::out); + + Ok = #ifdef WIN32 - aFacesFile->is_open() && aPointsFile->is_open(); + aFacesFile->is_open() && aPointsFile->is_open(); #else - aFacesFile.rdbuf()->is_open() && aPointsFile.rdbuf()->is_open(); + aFacesFile.rdbuf()->is_open() && aPointsFile.rdbuf()->is_open(); #endif - if (!Ok) - return error(dfltErr(), SMESH_Comment("Can't write into ") << aTmpDir.ToCString()); - - map aSmdsToGhs3dIdMap; - map aGhs3dIdToNodeMap; + if (!Ok) { + INFOS( "Can't write into " << aTmpDir.ToCString()); + return error(SMESH_Comment("Can't write into ") << aTmpDir); + } + map aSmdsToGhs3dIdMap; + map aGhs3dIdToNodeMap; - Ok = writePoints( aPointsFile, meshDS, aSmdsToGhs3dIdMap, aGhs3dIdToNodeMap ) && - writeFaces ( aFacesFile, meshDS, aSmdsToGhs3dIdMap ); + Ok = writePoints( aPointsFile, meshDS, aSmdsToGhs3dIdMap, aGhs3dIdToNodeMap ) && + writeFaces ( aFacesFile, meshDS, aSmdsToGhs3dIdMap ); - aFacesFile.close(); - aPointsFile.close(); + aFacesFile.close(); + aPointsFile.close(); - if ( ! Ok ) { - if ( !getenv("GHS3D_KEEP_FILES") ) { - OSD_File( aFacesFileName ).Remove(); - OSD_File( aPointsFileName ).Remove(); - } - return error(COMPERR_BAD_INPUT_MESH); + if ( ! Ok ) { + if ( !getenv("GHS3D_KEEP_FILES") ) { + OSD_File( aFacesFileName ).Remove(); + OSD_File( aPointsFileName ).Remove(); } + return error(COMPERR_BAD_INPUT_MESH); + } - // ----------------- - // run ghs3d mesher WIN32??? - // ----------------- + // ----------------- + // run ghs3d mesher WIN32??? + // ----------------- - // ghs3d need to know amount of memory it may use (MB). - // Default memory is defined at ghs3d installation but it may be not enough, - // so allow to use about all available memory + // ghs3d need to know amount of memory it may use (MB). + // Default memory is defined at ghs3d installation but it may be not enough, + // so allow to use about all available memory - TCollection_AsciiString memory; + TCollection_AsciiString memory; #ifndef WIN32 - struct sysinfo si; - int err = sysinfo( &si ); - if ( err == 0 ) { - int MB = 0.9 * ( si.freeram + si.freeswap ) * si.mem_unit / 1024 / 1024; - adjustMemory( MB, aLogFileName ); - memory = "-m "; - memory += MB; - } + struct sysinfo si; + int err = sysinfo( &si ); + if ( err == 0 ) { + int freeMem = si.totalram * si.mem_unit / 1024 / 1024; + memory = "-m "; + memory += int( 0.7 * freeMem ); + } #endif - MESSAGE("GHS3DPlugin_GHS3D::Compute"); - TCollection_AsciiString cmd( "ghs3d " ); // command to run - cmd += - memory + // memory - " -c0 -f " + aGenericName + // file to read - " 1>" + aLogFileName; // dump into file + MESSAGE("GHS3DPlugin_GHS3D::Compute"); + TCollection_AsciiString cmd( "ghs3d " ); // command to run + cmd += + memory + // memory + " -c0 -f " + aGenericName + // file to read + " 1>" + aLogFileName; // dump into file - system( cmd.ToCString() ); // run + system( cmd.ToCString() ); // run + + cout << endl; + cout << "End of Ghs3d execution !" << endl; + // -------------- + // read a result + // -------------- + + // Mapping the result file + + int fileOpen; + fileOpen = open( aResultFileName.ToCString(), O_RDONLY); + if ( fileOpen < 0 ) { cout << endl; - cout << "End of Ghs3d execution !" << endl; + cout << "Can't open the " << aResultFileName.ToCString() << " GHS3D output file" << endl; + Ok = false; + } + else + Ok = readResultFile( fileOpen, meshDS, tabShape, tabBox, _nbShape, aGhs3dIdToNodeMap ); - // -------------- - // read a result - // -------------- + // --------------------- + // remove working files + // --------------------- - // Mapping the result file + if ( Ok ) + { + OSD_File( aLogFileName ).Remove(); + } + else if ( OSD_File( aLogFileName ).Size() > 0 ) + { + INFOS( "GHS3D Error, see the " << aLogFileName.ToCString() << " file" ); - int fileOpen; - fileOpen = open( aResultFileName.ToCString(), O_RDONLY); - if ( fileOpen < 0 ) { - cout << endl; - cout << "Error when opening the " << aResultFileName.ToCString() << " file" << endl; - cout << endl; - Ok = false; + // get problem description from the log file + SMESH_Comment comment; + TCollection_AsciiString foundLine; + if ( findLineContaing( "has expired",aLogFileName,foundLine) && + foundLine.Search("Licence") >= 0) + { + foundLine.LeftAdjust(); + comment << foundLine; + } + if ( findLineContaing( "%% ERROR",aLogFileName,foundLine)) + { + foundLine.LeftAdjust(); + comment << foundLine; } + if ( findLineContaing( "%% NO SAVING OPERATION",aLogFileName,foundLine)) + { + comment << "Too many elements generated for a trial version.\n"; + } + if ( comment.empty() ) + comment << "See " << aLogFileName << " for problem description"; else - Ok = readResultFile( fileOpen, meshDS, tabShape, tabBox, _nbShape, aGhs3dIdToNodeMap ); + comment << "See " << aLogFileName << " for more information"; + error(COMPERR_ALGO_FAILED, comment); + } + else + { + // the log file is empty + OSD_File( aLogFileName ).Remove(); + INFOS( "GHS3D Error, command '" << cmd.ToCString() << "' failed" ); + error(COMPERR_ALGO_FAILED, "ghs3d: command not found" ); + } + + if ( !getenv("GHS3D_KEEP_FILES") ) { + OSD_File( aFacesFileName ).Remove(); + OSD_File( aPointsFileName ).Remove(); + OSD_File( aResultFileName ).Remove(); + OSD_File( aBadResFileName ).Remove(); + OSD_File( aBbResFileName ).Remove(); + } + cout << "<" << aResultFileName.ToCString() << "> GHS3D output file "; + if ( !Ok ) + cout << "not "; + cout << "treated !" << endl; + cout << endl; + _nbShape = 0; // re-initializing _nbShape for the next Compute() method call + delete [] tabShape; + delete [] tabBox; + + return Ok; +} + +//============================================================================= +/*! + *Here we are going to use the GHS3D mesher w/o geometry + */ +//============================================================================= +bool GHS3DPlugin_GHS3D::Compute(SMESH_Mesh& theMesh, + SMESH_MesherHelper* aHelper) +{ + MESSAGE("GHS3DPlugin_GHS3D::Compute()"); + + SMESHDS_Mesh* meshDS = theMesh.GetMeshDS(); + TopoDS_Shape theShape = aHelper->GetSubShape(); + + // make a unique working file name + // to avoid access to the same files by eg different users + + TCollection_AsciiString aGenericName, aTmpDir = getTmpDir(); + aGenericName = aTmpDir + "GHS3D_"; +#ifdef WIN32 + aGenericName += GetCurrentProcessId(); +#else + aGenericName += getpid(); +#endif + aGenericName += "_"; + aGenericName += meshDS->ShapeToIndex( theShape ); + + TCollection_AsciiString aFacesFileName, aPointsFileName, aResultFileName; + TCollection_AsciiString aBadResFileName, aBbResFileName, aLogFileName; + aFacesFileName = aGenericName + ".faces"; // in faces + aPointsFileName = aGenericName + ".points"; // in points + aResultFileName = aGenericName + ".noboite";// out points and volumes + aBadResFileName = aGenericName + ".boite"; // out bad result + aBbResFileName = aGenericName + ".bb"; // out vertex stepsize + aLogFileName = aGenericName + ".log"; // log + + // ----------------- + // make input files + // ----------------- + + ofstream aFacesFile ( aFacesFileName.ToCString() , ios::out); + ofstream aPointsFile ( aPointsFileName.ToCString() , ios::out); + bool Ok = +#ifdef WIN32 + aFacesFile->is_open() && aPointsFile->is_open(); +#else + aFacesFile.rdbuf()->is_open() && aPointsFile.rdbuf()->is_open(); +#endif + + if (!Ok) + return error( SMESH_Comment("Can't write into ") << aTmpDir.ToCString()); + + vector aNodeByGhs3dId; + + Ok = (writeFaces ( aFacesFile, meshDS, aNodeByGhs3dId ) && + writePoints( aPointsFile, meshDS, aNodeByGhs3dId)); + + aFacesFile.close(); + aPointsFile.close(); + + if ( ! Ok ) { + if ( !getenv("GHS3D_KEEP_FILES") ) { + OSD_File( aFacesFileName ).Remove(); + OSD_File( aPointsFileName ).Remove(); + } + return error(COMPERR_BAD_INPUT_MESH); + } + + // ----------------- + // run ghs3d mesher WIN32??? + // ----------------- + + // ghs3d need to know amount of memory it may use (MB). + // Default memory is defined at ghs3d installation but it may be not enough, + // so allow to use about all available memory + TCollection_AsciiString memory; +#ifdef WIN32 + // ???? +#else + struct sysinfo si; + int err = sysinfo( &si ); + if ( !err ) { + int freeMem = si.totalram * si.mem_unit / 1024 / 1024; + memory = "-m "; + memory += int( 0.7 * freeMem ); + } +#endif + + TCollection_AsciiString cmd( "ghs3d " ); // command to run + cmd += + memory + // memory + " -f " + aGenericName + // file to read + " 1>" + aLogFileName; // dump into file + + + + system( cmd.ToCString() ); // run + + // -------------- + // read a result + // -------------- + int fileOpen; + fileOpen = open( aResultFileName.ToCString(), O_RDONLY); + if ( fileOpen < 0 ) { + cout << endl; + cout << "Error when opening the " << aResultFileName.ToCString() << " file" << endl; + cout << endl; + Ok = false; + } + else { + Ok = readResultFile( fileOpen, meshDS, theShape ,aNodeByGhs3dId ); + } + // --------------------- // remove working files // --------------------- - if ( Ok ) { - OSD_File( aLogFileName ).Remove(); + if ( Ok ) + { + OSD_File( aLogFileName ).Remove(); + } + else if ( OSD_File( aLogFileName ).Size() > 0 ) + { + INFOS( "GHS3D Error, see the " << aLogFileName.ToCString() << " file" ); + + // get problem description from the log file + SMESH_Comment comment; + TCollection_AsciiString foundLine; + if ( findLineContaing( "has expired",aLogFileName,foundLine) && + foundLine.Search("Licence") >= 0) + { + foundLine.LeftAdjust(); + comment << foundLine; } - else if ( OSD_File( aLogFileName ).Size() > 0 ) { - Ok = error(dfltErr(), SMESH_Comment("See ")<< aLogFileName.ToCString() ); + if ( findLineContaing( "%% ERROR",aLogFileName,foundLine)) + { + foundLine.LeftAdjust(); + comment << foundLine; } - else { - OSD_File( aLogFileName ).Remove(); + if ( findLineContaing( "%% NO SAVING OPERATION",aLogFileName,foundLine)) + { + comment << "Too many elements generated for a trial version.\n"; } + if ( comment.empty() ) + comment << "See " << aLogFileName << " for problem description"; + else + comment << "See " << aLogFileName << " for more information"; + error(COMPERR_ALGO_FAILED, comment); + } + else { + // the log file is empty + OSD_File( aLogFileName ).Remove(); + INFOS( "GHS3D Error, command '" << cmd.ToCString() << "' failed" ); + error(COMPERR_ALGO_FAILED, "ghs3d: command not found" ); + } + + if ( !getenv("GHS3D_KEEP_FILES") ) + { + OSD_File( aFacesFileName ).Remove(); + OSD_File( aPointsFileName ).Remove(); + OSD_File( aResultFileName ).Remove(); + OSD_File( aBadResFileName ).Remove(); + OSD_File( aBbResFileName ).Remove(); } + return Ok; } + +//============================================================================= +/*! + * + */ +//============================================================================= + +ostream & GHS3DPlugin_GHS3D::SaveTo(ostream & save) +{ + return save; +} + +//============================================================================= +/*! + * + */ +//============================================================================= + +istream & GHS3DPlugin_GHS3D::LoadFrom(istream & load) +{ + return load; +} + +//============================================================================= +/*! + * + */ +//============================================================================= + +ostream & operator << (ostream & save, GHS3DPlugin_GHS3D & hyp) +{ + return hyp.SaveTo( save ); +} + +//============================================================================= +/*! + * + */ +//============================================================================= + +istream & operator >> (istream & load, GHS3DPlugin_GHS3D & hyp) +{ + return hyp.LoadFrom( load ); +} diff --git a/src/GHS3DPlugin_GHS3D.hxx b/src/GHS3DPlugin_GHS3D.hxx index 48625e6..05a3e10 100644 --- a/src/GHS3DPlugin_GHS3D.hxx +++ b/src/GHS3DPlugin_GHS3D.hxx @@ -18,6 +18,7 @@ // //============================================================================= // File : GHS3DPlugin_GHS3D.hxx +// Author : Edward AGAPOV, modified by Lioka RAZAFINDRAZAKA (CEA) 09/02/2007 // Project : SALOME // Copyright : CEA 2003 // $Header$ @@ -41,7 +42,15 @@ public: SMESH_Hypothesis::Hypothesis_Status& aStatus); virtual bool Compute(SMESH_Mesh& aMesh, - const TopoDS_Shape& aShape); + const TopoDS_Shape& aShape); + + virtual bool Compute(SMESH_Mesh& theMesh, + SMESH_MesherHelper* aHelper); + + ostream & SaveTo(ostream & save); + istream & LoadFrom(istream & load); + friend ostream & operator << (ostream & save, GHS3DPlugin_GHS3D & hyp); + friend istream & operator >> (istream & load, GHS3DPlugin_GHS3D & hyp); private: int _iShape; -- 2.39.2