From: eap Date: Fri, 2 Apr 2004 07:19:41 +0000 (+0000) Subject: Initial version X-Git-Tag: V1_0 X-Git-Url: http://git.salome-platform.org/gitweb/?a=commitdiff_plain;h=edd7bbf3a765fb25f04912ebafe91dbe2d34c9ab;p=plugins%2Fghs3dplugin.git Initial version --- diff --git a/src/GHS3DPlugin_GHS3D.cxx b/src/GHS3DPlugin_GHS3D.cxx new file mode 100644 index 0000000..6393ab9 --- /dev/null +++ b/src/GHS3DPlugin_GHS3D.cxx @@ -0,0 +1,473 @@ +//============================================================================= +// File : GHS3DPlugin_GHS3D.cxx +// Created : +// Author : Edward AGAPOV +// Project : SALOME +// Copyright : CEA 2003 +// $Header$ +//============================================================================= +using namespace std; + +#include "GHS3DPlugin_GHS3D.hxx" +#include "SMESH_Gen.hxx" +#include "SMESH_Mesh.hxx" + +#include "SMDS_MeshElement.hxx" +#include "SMDS_MeshNode.hxx" + +#include + +#include "utilities.h" + +#include + +#ifdef _DEBUG_ +#define DUMP(txt) \ +// cout << txt +#else +#define DUMP(txt) +#endif + +//============================================================================= +/*! + * + */ +//============================================================================= + +GHS3DPlugin_GHS3D::GHS3DPlugin_GHS3D(int hypId, int studyId, SMESH_Gen* gen) + : SMESH_3D_Algo(hypId, studyId, gen) +{ + MESSAGE("GHS3DPlugin_GHS3D::GHS3DPlugin_GHS3D"); + _name = "GHS3D"; + _shapeType = (1 << TopAbs_SHELL) | (1 << TopAbs_SOLID);// 1 bit /shape type +} + +//============================================================================= +/*! + * + */ +//============================================================================= + +GHS3DPlugin_GHS3D::~GHS3DPlugin_GHS3D() +{ + MESSAGE("GHS3DPlugin_GHS3D::~GHS3DPlugin_GHS3D"); +} + +//============================================================================= +/*! + * + */ +//============================================================================= + +bool GHS3DPlugin_GHS3D::CheckHypothesis + (SMESH_Mesh& aMesh, + const TopoDS_Shape& aShape, + SMESH_Hypothesis::Hypothesis_Status& aStatus) +{ +// MESSAGE("GHS3DPlugin_GHS3D::CheckHypothesis"); + aStatus = SMESH_Hypothesis::HYP_OK; + return true; +} + +//======================================================================= +//function : writeFaces +//purpose : +//======================================================================= + +static bool writeFaces (ofstream & theFile, + SMESHDS_Mesh * theMesh, + const map & theSmdsToGhs3dIdMap) +{ + // 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 = theMesh->NbFaces(); + if ( nbFaces == 0 ) + return false; + + const char* space = " "; + const int dummyint = 0; + + // NB_ELEMS DUMMY_INT + theFile << space << nbFaces << space << dummyint << endl; + + // Loop from 1 to NB_ELEMS + SMDS_FaceIteratorPtr it = theMesh->facesIterator(); + while ( it->more() ) + { + // NB_NODES + const SMDS_MeshElement* elem = it->next(); + const int nbNodes = elem->NbNodes(); + theFile << space << nbNodes; + + // NODE_NB_1 NODE_NB_2 ... + SMDS_ElemIteratorPtr nodeIt = elem->nodesIterator(); + while ( nodeIt->more() ) + { + // find GHS3D ID + int aSmdsID = nodeIt->next()->GetID(); + map::const_iterator it = theSmdsToGhs3dIdMap.find( aSmdsID ); + ASSERT( it != theSmdsToGhs3dIdMap.end() ); + theFile << space << (*it).second; + } + + // (NB_NODES + 1) times: DUMMY_INT + for ( int i=0; i<=nbNodes; i++) + theFile << space << dummyint; + + theFile << endl; + } + + return true; +} + +//======================================================================= +//function : writePoints +//purpose : +//======================================================================= + +static bool writePoints (ofstream & theFile, + SMESHDS_Mesh * theMesh, + map & theSmdsToGhs3dIdMap, + map & theGhs3dIdToNodeMap) +{ + // structure: + // + // NB_NODES + // Loop from 1 to NB_NODES + // X Y Z DUMMY_INT + + int nbNodes = theMesh->NbNodes(); + if ( nbNodes == 0 ) + return false; + + const char* space = " "; + const int dummyint = 0; + + // NB_NODES + theFile << space << nbNodes << endl; + + // Loop from 1 to NB_NODES + int aGhs3dID = 1; + SMDS_NodeIteratorPtr it = theMesh->nodesIterator(); + while ( it->more() ) + { + const SMDS_MeshNode* node = it->next(); + theSmdsToGhs3dIdMap.insert( map ::value_type( node->GetID(), aGhs3dID )); + theGhs3dIdToNodeMap.insert (map ::value_type( aGhs3dID, node )); + aGhs3dID++; + + // X Y Z DUMMY_INT + theFile + << space << node->X() + << space << node->Y() + << space << node->Z() + << space << dummyint; + + theFile << endl; + } + + return true; +} + +//======================================================================= +//function : getInt +//purpose : +//======================================================================= + +static bool getInt( int & theValue, char * & theLine ) +{ + char *ptr; + theValue = strtol( theLine, &ptr, 10 ); + if ( ptr == theLine || + // there must not be neither '.' nor ',' nor 'E' ... + (*ptr != ' ' && *ptr != '\n' && *ptr != '\0')) + return false; + + DUMP( " " << theValue ); + theLine = ptr; + return true; +} + +//======================================================================= +//function : getDouble +//purpose : +//======================================================================= + +static bool getDouble( double & theValue, char * & theLine ) +{ + char *ptr; + theValue = strtod( theLine, &ptr ); + if ( ptr == theLine ) + return false; + + DUMP( " " << theValue ); + theLine = ptr; + return true; +} + +//======================================================================= +//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 : readResult +//purpose : +//======================================================================= + +static bool readResult(FILE * theFile, + SMESHDS_Mesh * theMesh, + const TopoDS_Shape& theShape, + map & theGhs3dIdToNodeMap) +{ + // structure: + + // record 1: + // NB_ELEMENTS NB_NODES NB_INPUT_NODES (14 DUMMY_INT) + // record 2: + // (NB_ELEMENTS * 4) node nbs + // record 3: + // (NB_NODES) node XYZ + + char aBuffer[ GHS3DPlugin_BUFLENGTH ]; + char * aPtr; + int aLineNb = 0; + + // get shell to set nodes in + TopExp_Explorer exp( theShape, TopAbs_SHELL ); + TopoDS_Shell aShell = TopoDS::Shell( exp.Current() ); + + // ------------------------------------- + // record 1: + // read nb generated elements and nodes + // ------------------------------------- + int nbElems = 0 , nbNodes = 0, nbInputNodes = 0; + GHS3DPlugin_ReadLine( aPtr, aBuffer, theFile, aLineNb ); + if (!aPtr || + !getInt( nbElems, aPtr ) || + !getInt( nbNodes, aPtr ) || + !getInt( nbInputNodes, aPtr)) + return false; + + // ------------------------------------------- + // record 2: + // read element nodes and create tetrahedrons + // ------------------------------------------- + GHS3DPlugin_ReadLine( aPtr, aBuffer, theFile, aLineNb ); + for (int iElem = 0; iElem < nbElems; iElem++) + { + // read 4 nodes + const SMDS_MeshNode * node[4]; + for (int iNode = 0; iNode < 4; iNode++) + { + // read Ghs3d node ID + int ID = 0; + if (!aPtr || ! getInt ( ID, aPtr )) + { + GHS3DPlugin_ReadLine( aPtr, aBuffer, theFile, aLineNb ); + if (!aPtr || ! getInt ( ID, aPtr )) + { + MESSAGE( "Cant read " << (iNode+1) << "-th node on line " << aLineNb ); + return false; + } + } + // find/create a node with ID + map ::iterator IdNode = theGhs3dIdToNodeMap.find( ID ); + if ( IdNode == theGhs3dIdToNodeMap.end()) + { + // ID is not yet in theGhs3dIdToNodeMap + ASSERT ( ID > nbInputNodes ); // it should be a new one + SMDS_MeshNode * aNewNode = theMesh->AddNode( 0.,0.,0. ); // read XYZ later + theMesh->SetNodeInVolume( aNewNode, aShell ); + theGhs3dIdToNodeMap.insert + ( map ::value_type( ID, aNewNode )); + node[ iNode ] = aNewNode; + } + else + { + node[ iNode ] = (*IdNode).second; + } + } + // create a tetrahedron + SMDS_MeshElement* aTet = theMesh->AddVolume( node[0], node[1], node[2], node[3] ); + theMesh->SetMeshElementOnShape( aTet, theShape ); + } + + // ------------------------ + // record 3: + // read and set nodes' XYZ + // ------------------------ + GHS3DPlugin_ReadLine( aPtr, aBuffer, theFile, aLineNb ); + for (int iNode = 0; iNode < nbNodes; iNode++) + { + // read 3 coordinates + double coord [3]; + for (int iCoord = 0; iCoord < 3; iCoord++) + { + if (!aPtr || ! getDouble ( coord[ iCoord ], aPtr )) + { + GHS3DPlugin_ReadLine( aPtr, aBuffer, theFile, aLineNb ); + if (!aPtr || ! getDouble ( coord[ iCoord ], aPtr )) + { + MESSAGE( "Cant read " << (iCoord+1) << "-th node coord on line " << aLineNb ); + return false; + } + } + } + // do not move old nodes + int ID = iNode + 1; + if (ID <= nbInputNodes) + continue; + // find a node + map ::iterator IdNode = theGhs3dIdToNodeMap.find( ID ); + ASSERT ( IdNode != theGhs3dIdToNodeMap.end()); + SMDS_MeshNode* node = const_cast ( (*IdNode).second ); + + // set XYZ + theMesh->MoveNode( node, coord[0], coord[1], coord[2] ); + } + + return true; +} + +//============================================================================= +/*! + *Here we are going to use the GHS3D mesher + */ +//============================================================================= + +bool GHS3DPlugin_GHS3D::Compute(SMESH_Mesh& theMesh, + const TopoDS_Shape& theShape) +{ + MESSAGE("GHS3DPlugin_GHS3D::Compute"); + + // working dir + const char* wdName = "tmp"; + QDir wd = QDir::root(); // "/" + if ( !wd.cd( wdName ) ) { // "/tmp" + MESSAGE( "Cannot find the " << wdName << " directory" ); + return false; + } + + const QString aGenericName = wd.filePath( "GHS3DTMP" ); + const QString aFacesFileName = aGenericName + ".faces"; + const QString aPointsFileName = aGenericName + ".points"; + const QString aResultFileName = aGenericName + ".noboite"; + const QString aErrorFileName = aGenericName + ".error"; + + // remove old files + QFile( aFacesFileName ).remove(); + QFile( aPointsFileName ).remove(); + QFile( aResultFileName ).remove(); + QFile( aErrorFileName ).remove(); + + + // ----------------- + // make input files + // ----------------- + + ofstream aFacesFile ( aFacesFileName.latin1() , ios::out); + ofstream aPointsFile ( aPointsFileName.latin1() , ios::out); + if (!aFacesFile || !aFacesFile.rdbuf()->is_open() || + !aPointsFile || !aPointsFile.rdbuf()->is_open()) + { + MESSAGE( "Can't write into " << wdName << " directory"); + return false; + } + SMESHDS_Mesh* meshDS = theMesh.GetMeshDS(); + map aSmdsToGhs3dIdMap; + map aGhs3dIdToNodeMap; + + bool Ok = + (writePoints( aPointsFile, meshDS, aSmdsToGhs3dIdMap, aGhs3dIdToNodeMap ) && + writeFaces ( aFacesFile, meshDS, aSmdsToGhs3dIdMap )); + + aFacesFile.close(); + aPointsFile.close(); + + if ( ! Ok ) + return false; + + // ----------------- + // run ghs3d mesher + // ----------------- + + QString cmd = "ghs3d " + "-m 1000 " // memory: 1000 M + "-f " + aGenericName + // file to read + " 1>" + aErrorFileName; // dump into file + if (system(cmd.latin1())) + { + MESSAGE ("Failed: <" << cmd.latin1() << ">"); + return false; + } + + // -------------- + // read a result + // -------------- + + FILE * aResultFile = fopen( aResultFileName.latin1(), "r" ); + if (!aResultFile) + { + MESSAGE( "GHS3D ERROR: see " << aErrorFileName.latin1() ); + return false; + } + + Ok = readResult( aResultFile, meshDS, theShape, aGhs3dIdToNodeMap ); + fclose(aResultFile); + + 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 ); +}