From: gdd Date: Fri, 18 Feb 2011 15:32:35 +0000 (+0000) Subject: Refactoring of directory structure X-Git-Tag: Start_BR_19998_21191~2 X-Git-Url: http://git.salome-platform.org/gitweb/?a=commitdiff_plain;h=cfbcbc191485567ab9f721d662d27fd3771c6e5f;p=plugins%2Fghs3dplugin.git Refactoring of directory structure --- diff --git a/clean_configure b/clean_configure index 294e047..ec47141 100755 --- a/clean_configure +++ b/clean_configure @@ -21,13 +21,20 @@ rm -rf autom4te.cache aclocal.m4 configure make_config find . -name "*~" -print -exec rm {} \; find . -name "*.pyc" -print -exec rm {} \; -#exit -# ==================== ON SORT AVANT find bin -name Makefile.in | xargs rm -f -find doc -name Makefile.in | xargs rm -f find idl -name Makefile.in | xargs rm -f find resources -name Makefile.in | xargs rm -f -find salome_adm -name Makefile.in | xargs rm -f +find adm_local -name Makefile.in | xargs rm -f find src -name Makefile.in | xargs rm -f +rm -f adm_local/unix/config_files/config* +rm -f adm_local/unix/config_files/depcomp +rm -f adm_local/unix/config_files/install-sh +rm -f adm_local/unix/config_files/libtool.m4 +rm -f adm_local/unix/config_files/ltmain.sh +rm -f adm_local/unix/config_files/ltoptions.m4 +rm -f adm_local/unix/config_files/ltsugar.m4 +rm -f adm_local/unix/config_files/ltversion.m4 +rm -f adm_local/unix/config_files/lt~obsolete.m4 +rm -f adm_local/unix/config_files/missing rm -f Makefile.in diff --git a/configure.ac b/configure.ac index 05ee1a7..f0999ac 100644 --- a/configure.ac +++ b/configure.ac @@ -419,6 +419,7 @@ AC_OUTPUT([ \ GHS3DPLUGIN_version.h \ src/Makefile \ src/GUI/Makefile \ + src/GHS3DPlugin/Makefile \ resources/Makefile \ idl/Makefile \ Makefile \ diff --git a/src/GHS3DPlugin/GHS3DPlugin_Defs.hxx b/src/GHS3DPlugin/GHS3DPlugin_Defs.hxx new file mode 100644 index 0000000..0d9f927 --- /dev/null +++ b/src/GHS3DPlugin/GHS3DPlugin_Defs.hxx @@ -0,0 +1,37 @@ +// Copyright (C) 2004-2010 CEA/DEN, EDF R&D +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +//============================================================================= +// File : GHS3DPlugin_Defs.hxx +// Author : Alexander A. BORODIN +// +#ifndef _GHS3DPlugin_DEFS_HXX_ +#define _GHS3DPlugin_DEFS_HXX_ + +#ifdef WIN32 + #if defined GHS3DPLUGIN_EXPORTS || defined GHS3DEngine_EXPORTS + #define GHS3DPLUGIN_EXPORT __declspec( dllexport ) + #else + #define GHS3DPLUGIN_EXPORT __declspec( dllimport ) + #endif +#else + #define GHS3DPLUGIN_EXPORT +#endif + +#endif diff --git a/src/GHS3DPlugin/GHS3DPlugin_GHS3D.cxx b/src/GHS3DPlugin/GHS3DPlugin_GHS3D.cxx new file mode 100644 index 0000000..74f3186 --- /dev/null +++ b/src/GHS3DPlugin/GHS3DPlugin_GHS3D.cxx @@ -0,0 +1,2154 @@ +// Copyright (C) 2004-2010 CEA/DEN, EDF R&D +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +//============================================================================= +// File : GHS3DPlugin_GHS3D.cxx +// Created : +// Author : Edward AGAPOV, modified by Lioka RAZAFINDRAZAKA (CEA) 09/02/2007 +// Project : SALOME +//============================================================================= +// +#include "GHS3DPlugin_GHS3D.hxx" +#include "GHS3DPlugin_Hypothesis.hxx" + + +#include + +#include "SMESH_Gen.hxx" +#include "SMESH_Mesh.hxx" +#include "SMESH_Comment.hxx" +#include "SMESH_MesherHelper.hxx" +#include "SMESH_MeshEditor.hxx" + +#include "SMDS_MeshElement.hxx" +#include "SMDS_MeshNode.hxx" +#include "SMDS_FaceOfNodes.hxx" +#include "SMDS_VolumeOfNodes.hxx" + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +//#include +#include +#include +#include + +#include "utilities.h" + +#ifdef WIN32 +#include +#else +#include +#endif + +using namespace std; + +//#include + + +#define castToNode(n) static_cast( n ); + +#ifdef _DEBUG_ +#define DUMP(txt) \ +// std::cout << txt +#else +#define DUMP(txt) +#endif + +extern "C" +{ +#ifndef WNT +#include +#include +#endif +#include +#include +} + +#define HOLE_ID -1 + +typedef const list TTriaList; + +static void removeFile( const TCollection_AsciiString& fileName ) +{ + try { + OSD_File( fileName ).Remove(); + } + catch ( Standard_ProgramError ) { + MESSAGE("Can't remove file: " << fileName.ToCString() << " ; file does not exist or permission denied"); + } +} + +//============================================================================= +/*! + * + */ +//============================================================================= + +GHS3DPlugin_GHS3D::GHS3DPlugin_GHS3D(int hypId, int studyId, SMESH_Gen* gen) + : SMESH_3D_Algo(hypId, studyId, 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; + _compatibleHypothesis.push_back("GHS3D_Parameters"); + _compatibleHypothesis.push_back( StdMeshers_ViscousLayers::GetHypType() ); + _requireShape = false; // can work without shape +} + +//============================================================================= +/*! + * + */ +//============================================================================= + +GHS3DPlugin_GHS3D::~GHS3DPlugin_GHS3D() +{ + MESSAGE("GHS3DPlugin_GHS3D::~GHS3DPlugin_GHS3D"); +} + +//============================================================================= +/*! + * + */ +//============================================================================= + +bool GHS3DPlugin_GHS3D::CheckHypothesis ( SMESH_Mesh& aMesh, + const TopoDS_Shape& aShape, + Hypothesis_Status& aStatus ) +{ + aStatus = SMESH_Hypothesis::HYP_OK; + + _hyp = 0; + _viscousLayersHyp = 0; + _keepFiles = false; + + const list & hyps = + GetUsedHypothesis(aMesh, aShape, /*ignoreAuxiliary=*/false); + list ::const_iterator h = hyps.begin(); + for ( ; h != hyps.end(); ++h ) + { + if ( !_hyp ) + _hyp = dynamic_cast< const GHS3DPlugin_Hypothesis*> ( *h ); + if ( !_viscousLayersHyp ) + _viscousLayersHyp = dynamic_cast< const StdMeshers_ViscousLayers*> ( *h ); + } + if ( _hyp ) + _keepFiles = _hyp->GetKeepFiles(); + + 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, + TopAbs_State * state = 0) +{ + gp_XYZ aPnt(0,0,0); + int j, iShape, nbNode = 4; + + for ( j=0; jX(), aNode[j]->Y(), aNode[j]->Z() ); + if ( aNode[j]->GetPosition()->GetTypeOfPosition() == SMDS_TOP_3DSPACE ) { + aPnt = p; + break; + } + aPnt += p / nbNode; + } + + BRepClass3d_SolidClassifier SC (aShape, aPnt, Precision::Confusion()); + if (state) *state = SC.State(); + if ( SC.State() != TopAbs_IN || aShape.IsNull() || aShape.ShapeType() != TopAbs_SOLID) { + for (iShape = 0; iShape < nShape; iShape++) { + aShape = shape[iShape]; + if ( !( aPnt.X() < box[iShape][0] || box[iShape][1] < aPnt.X() || + aPnt.Y() < box[iShape][2] || box[iShape][3] < aPnt.Y() || + aPnt.Z() < box[iShape][4] || box[iShape][5] < aPnt.Z()) ) { + BRepClass3d_SolidClassifier SC (aShape, aPnt, Precision::Confusion()); + if (state) *state = SC.State(); + if (SC.State() == TopAbs_IN) + break; + } + } + } + return aShape; +} + +//======================================================================= +//function : readMapIntLine +//purpose : +//======================================================================= + +static char* readMapIntLine(char* ptr, int tab[]) { + long int intVal; + std::cout << std::endl; + + for ( int i=0; i<17; i++ ) { + intVal = strtol(ptr, &ptr, 10); + if ( i < 3 ) + tab[i] = intVal; + } + return ptr; +} + +//======================================================================= +//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 : +//======================================================================= + +static bool writeFaces (ofstream & theFile, + const SMESH_ProxyMesh& theMesh, + const TopoDS_Shape& theShape, + const map & theSmdsToGhs3dIdMap) +{ + // 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 + + TopoDS_Shape aShape; + const SMESHDS_SubMesh* theSubMesh; + const SMDS_MeshElement* aFace; + const char* space = " "; + const int dummyint = 0; + map::const_iterator itOnMap; + SMDS_ElemIteratorPtr itOnSubMesh, itOnSubFace; + int nbNodes, aSmdsID; + + // count triangles bound to geometry + int nbTriangles = 0; + + TopTools_IndexedMapOfShape facesMap; + TopExp::MapShapes( theShape, TopAbs_FACE, facesMap ); + + for ( int i = 1; i <= facesMap.Extent(); ++i ) + if (( theSubMesh = theMesh.GetSubMesh( facesMap(i)))) + nbTriangles += theSubMesh->NbElements(); + + std::cout << " " << facesMap.Extent() << " shapes of 2D dimension" << std::endl; + std::cout << std::endl; + + theFile << space << nbTriangles << space << dummyint << std::endl; + + for ( int i = 1; i <= facesMap.Extent(); i++ ) + { + aShape = facesMap(i); + theSubMesh = theMesh.GetSubMesh(aShape); + if ( !theSubMesh ) continue; + 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 ); + // if ( itOnMap == theSmdsToGhs3dIdMap.end() ) { + // cout << "not found node: " << aSmdsID << endl; + // return false; + // } + 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 << std::endl; + } + } + + return true; +} + +//======================================================================= +//function : writeFaces +//purpose : Write Faces in case if generate 3D mesh w/o geometry +//======================================================================= + +static bool writeFaces (ofstream & theFile, + const SMESH_ProxyMesh& 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 nbNodes, nbTriangles = 0; + map< const SMDS_MeshNode*,int >::iterator it; + SMDS_ElemIteratorPtr nodeIt; + const SMDS_MeshElement* elem; + + const char* space = " "; + const int dummyint = 0; + + // count faces + nbTriangles = theMesh.NbFaces(); + + if ( nbTriangles == 0 ) + return false; + + std::cout << "The initial 2D mesh contains " << nbTriangles << " faces and "; + + // NB_ELEMS DUMMY_INT + theFile << space << nbTriangles << space << dummyint << std::endl; + + + map aNodeToGhs3dIdMap; + + // Loop from 1 to NB_ELEMS + + SMDS_ElemIteratorPtr eIt = theMesh.GetFaces(); + while ( eIt->more() ) + { + elem = eIt->next(); + // NB_NODES PER FACE + nbNodes = elem->NbNodes(); + theFile << space << nbNodes; + + // NODE_NB_1 NODE_NB_2 ... + nodeIt = elem->nodesIterator(); + while ( nodeIt->more() ) + { + // find GHS3D ID + 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 + for ( int i=0; i<=nbNodes; i++) + theFile << space << dummyint; + theFile << std::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; +} + +//======================================================================= +//function : writePoints +//purpose : +//======================================================================= + +static bool writePoints (ofstream & theFile, + SMESH_MesherHelper& theHelper, + map & theSmdsToGhs3dIdMap, + map & theGhs3dIdToNodeMap, + map,double> & theEnforcedVertices) +{ + // record structure: + // + // NB_NODES + // Loop from 1 to NB_NODES + // X Y Z DUMMY_INT + + SMESHDS_Mesh * theMesh = theHelper.GetMeshDS(); + int nbNodes = theMesh->NbNodes(); + if ( nbNodes == 0 ) + return false; + int nbEnforcedVertices = theEnforcedVertices.size(); + + // Issue 020674: EDF 870 SMESH: Mesh generated by Netgen not usable by GHS3D + // The problem is in nodes on degenerated edges, we need to skip them + if ( theHelper.HasDegeneratedEdges() ) + { + // here we decrease total nb of nodes by nb of nodes on degenerated edges + set checkedSM; + for (TopExp_Explorer e(theMesh->ShapeToMesh(), TopAbs_EDGE ); e.More(); e.Next()) + { + SMESH_subMesh* sm = theHelper.GetMesh()->GetSubMesh( e.Current() ); + if ( checkedSM.insert( sm->GetId() ).second && theHelper.IsDegenShape(sm->GetId() )) { + if ( sm->GetSubMeshDS() ) + nbNodes -= sm->GetSubMeshDS()->NbNodes(); + } + } + } + const char* space = " "; + const int dummyint = 0; + + int aGhs3dID = 1; + SMDS_NodeIteratorPtr it = theMesh->nodesIterator(); + const SMDS_MeshNode* node; + + // NB_NODES + std::cout << std::endl; + std::cout << "The initial 2D mesh contains :" << std::endl; + std::cout << " " << nbNodes << " nodes" << std::endl; + if (nbEnforcedVertices > 0) { + std::cout << " " << nbEnforcedVertices << " enforced vertices" << std::endl; + } + std::cout << std::endl; + std::cout << "Start writing in 'points' file ..." << std::endl; + theFile << space << nbNodes << std::endl; + + // Loop from 1 to NB_NODES + + while ( it->more() ) + { + node = it->next(); + if ( node->GetPosition()->GetTypeOfPosition() == SMDS_TOP_EDGE && + theHelper.IsDegenShape( node->getshapeId() )) // Issue 020674 + continue; + + theSmdsToGhs3dIdMap.insert( make_pair( node->GetID(), aGhs3dID )); + theGhs3dIdToNodeMap.insert( make_pair( aGhs3dID, node )); + aGhs3dID++; + + // X Y Z DUMMY_INT + theFile + << space << node->X() + << space << node->Y() + << space << node->Z() + << space << dummyint; + + theFile << std::endl; + + } + + // Iterate over the enforced vertices + GHS3DPlugin_Hypothesis::TEnforcedVertexValues::const_iterator vertexIt; + const TopoDS_Shape shapeToMesh = theMesh->ShapeToMesh(); + for(vertexIt = theEnforcedVertices.begin() ; vertexIt != theEnforcedVertices.end() ; ++vertexIt) { + double x = vertexIt->first[0]; + double y = vertexIt->first[1]; + double z = vertexIt->first[2]; + // Test if point is inside shape to mesh + gp_Pnt myPoint(x,y,z); + BRepClass3d_SolidClassifier scl(shapeToMesh); + scl.Perform(myPoint, 1e-7); + TopAbs_State result = scl.State(); + if ( result == TopAbs_IN ) { + MESSAGE("Adding enforced vertex (" << x << "," << y <<"," << z << ") = " << vertexIt->second); + // X Y Z PHY_SIZE DUMMY_INT + theFile + << space << x + << space << y + << space << z + << space << vertexIt->second + << space << dummyint; + + theFile << std::endl; + } + else + MESSAGE("Enforced vertex (" << x << "," << y <<"," << z << ") is not inside the geometry: it was not added "); + } + + + std::cout << std::endl; + std::cout << "End writing in 'points' file." << std::endl; + + return true; +} + +//======================================================================= +//function : writePoints +//purpose : +//======================================================================= + +static bool writePoints (ofstream & theFile, + SMESH_Mesh * theMesh, + const vector & theNodeByGhs3dId, + map,double> & theEnforcedVertices) +{ + // record structure: + // + // NB_NODES + // Loop from 1 to NB_NODES + // X Y Z DUMMY_INT + + int nbNodes = theNodeByGhs3dId.size(); + if ( nbNodes == 0 ) + return false; + + int nbEnforcedVertices = theEnforcedVertices.size(); + + const char* space = " "; + const int dummyint = 0; + + const SMDS_MeshNode* node; + + // NB_NODES + std::cout << std::endl; + std::cout << "The initial 2D mesh contains :" << std::endl; + std::cout << " " << nbNodes << " nodes" << std::endl; + std::cout << " " << nbEnforcedVertices << " enforced vertices" << std::endl; + std::cout << std::endl; + std::cout << "Start writing in 'points' file ..." << std::endl; + theFile << space << nbNodes << std::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 << std::endl; + + } + + // Iterate over the enforced vertices + GHS3DPlugin_Hypothesis::TEnforcedVertexValues::const_iterator vertexIt; + auto_ptr< SMESH_ElementSearcher > pntCls ( SMESH_MeshEditor( theMesh ).GetElementSearcher()); + for(vertexIt = theEnforcedVertices.begin() ; vertexIt != theEnforcedVertices.end() ; ++vertexIt) { + double x = vertexIt->first[0]; + double y = vertexIt->first[1]; + double z = vertexIt->first[2]; + // Test if point is inside shape to mesh + gp_Pnt myPoint(x,y,z); + TopAbs_State result = pntCls->GetPointState( myPoint ); + if ( result == TopAbs_IN ) { + std::cout << "Adding enforced vertex (" << x << "," << y <<"," << z << ") = " << vertexIt->second << std::endl; + + // X Y Z PHY_SIZE DUMMY_INT + theFile + << space << x + << space << y + << space << z + << space << vertexIt->second + << space << dummyint; + + theFile << std::endl; + } + } + std::cout << std::endl; + std::cout << "End writing in 'points' file." << std::endl; + + 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 : +//======================================================================= + +static bool readResultFile(const int fileOpen, +#ifdef WNT + const char* fileName, +#endif + SMESH_Mesh& theMesh, + TopoDS_Shape tabShape[], + double** tabBox, + const int nbShape, + map & theGhs3dIdToNodeMap, + bool toMeshHoles, + int nbEnforcedVertices) +{ + MESSAGE("GHS3DPlugin_GHS3D::readResultFile()"); + Kernel_Utils::Localizer loc; + struct stat status; + size_t length; + + char *ptr, *mapPtr; + char *tetraPtr; + char *shapePtr; + + SMESHDS_Mesh* theMeshDS = theMesh.GetMeshDS(); + + int fileStat; + int nbElems, nbNodes, nbInputNodes; + int nodeId/*, triangleId*/; + int nbTriangle; + int ID, shapeID, ghs3dShapeID; + int IdShapeRef = 1; + int compoundID = + nbShape ? theMeshDS->ShapeToIndex( tabShape[0] ) : 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; +#ifdef _DEBUG_ + set shapeIDs; +#endif + + // Read the file state + fileStat = fstat(fileOpen, &status); + length = status.st_size; + + // Mapping the result file into memory +#ifdef WNT + HANDLE fd = CreateFile(fileName, 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; + + nbElems = tab[0]; + nbNodes = tab[1]; + nbInputNodes = tab[2]; + + nodeAssigne = new int[ nbNodes+1 ]; + + if (nbShape > 0) + aSolid = tabShape[0]; + + // Reading the nodeId + for (int i=0; i < 4*nbElems; i++) + nodeId = strtol(ptr, &ptr, 10); + + MESSAGE("nbInputNodes: "< (nbInputNodes-nbEnforcedVertices) ) { + // Creating SMESH nodes + // - for enforced vertices + // - for vertices of forced edges + // - for ghs3d nodes + nodeAssigne[ iNode ] = 0; + aNewNode = theMeshDS->AddNode( coord[0],coord[1],coord[2] ); + theGhs3dIdToNodeMap.insert(theGhs3dIdToNodeMap.end(), make_pair( iNode, aNewNode )); + } + } + + // Reading the number of triangles which corresponds to the number of sub-domains + nbTriangle = strtol(ptr, &ptr, 10); + + tabID = new int[nbTriangle]; + for (int i=0; i < nbTriangle; i++) { + tabID[i] = 0; + // find the solid corresponding to GHS3D sub-domain following + // the technique proposed in GHS3D manual in chapter + // "B.4 Subdomain (sub-region) assignment" + int nodeId1 = strtol(ptr, &ptr, 10); + int nodeId2 = strtol(ptr, &ptr, 10); + int nodeId3 = strtol(ptr, &ptr, 10); + if ( nbTriangle > 1 ) { + 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 + } + } + } + + shapePtr = ptr; + + if ( nbTriangle <= nbShape ) // no holes + toMeshHoles = true; // not avoid creating tetras in holes + + // 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; + } + // 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 + //aTet = theMeshDS->AddVolume( node[1], node[0], node[2], node[3] ); + if ( nbTriangle > 1 ) { + shapeID = HOLE_ID; // negative shapeID means not to create tetras if !toMeshHoles + ghs3dShapeID = strtol(shapePtr, &shapePtr, 10) - IdShapeRef; + if ( tabID[ ghs3dShapeID ] == 0 ) { + TopAbs_State state; + aSolid = findShape(node, aSolid, tabShape, tabBox, nbShape, &state); + if ( toMeshHoles || state == TopAbs_IN ) + shapeID = theMeshDS->ShapeToIndex( aSolid ); + tabID[ ghs3dShapeID ] = shapeID; + } + else + shapeID = tabID[ ghs3dShapeID ]; + } + 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 + shapeID = 0; + for ( int i=0; i<4 && shapeID==0; i++ ) { + if ( nodeAssigne[ nodeID[i] ] == 1 && + node[i]->GetPosition()->GetTypeOfPosition() == SMDS_TOP_3DSPACE && + node[i]->getshapeId() > 1 ) + { + shapeID = node[i]->getshapeId(); + } + } + if ( shapeID==0 ) { + aSolid = findShape(node, aSolid, tabShape, tabBox, nbShape); + shapeID = theMeshDS->ShapeToIndex( aSolid ); + } + } + // set new nodes and tetrahedron onto the shape + for ( int i=0; i<4; i++ ) { + if ( nodeAssigne[ nodeID[i] ] == 0 ) { + if ( shapeID != HOLE_ID ) + theMeshDS->SetNodeInVolume( node[i], shapeID ); + nodeAssigne[ nodeID[i] ] = shapeID; + } + } + if ( toMeshHoles || shapeID != HOLE_ID ) { + aTet = theMeshDS->AddVolume( node[1], node[0], node[2], node[3] ); + theMeshDS->SetMeshElementOnShape( aTet, shapeID ); + } +#ifdef _DEBUG_ + shapeIDs.insert( shapeID ); +#endif + } + // Remove nodes of tetras inside holes if !toMeshHoles + if ( !toMeshHoles ) { + itOnNode = theGhs3dIdToNodeMap.find( nbInputNodes ); + for ( ; itOnNode != theGhs3dIdToNodeMap.end(); ++itOnNode) { + ID = itOnNode->first; + if ( nodeAssigne[ ID ] == HOLE_ID ) + theMeshDS->RemoveFreeNode( itOnNode->second, 0 ); + } + } + + if ( nbElems ) + cout << nbElems << " tetrahedrons have been associated to " << nbShape << " shapes" << endl; +#ifdef WNT + UnmapViewOfFile(mapPtr); + CloseHandle(hMapObject); + CloseHandle(fd); +#else + munmap(mapPtr, length); +#endif + close(fileOpen); + + delete [] tab; + delete [] tabID; + delete [] nodeID; + delete [] coord; + delete [] node; + delete [] nodeAssigne; + +#ifdef _DEBUG_ + shapeIDs.erase(-1); + if ( shapeIDs.size() != nbShape ) { + std::cout << "Only " << shapeIDs.size() << " solids of " << nbShape << " found" << std::endl; + for (int i=0; iShapeToIndex( tabShape[i] ); + if ( shapeIDs.find( shapeID ) == shapeIDs.end() ) + std::cout << " Solid #" << shapeID << " not found" << std::endl; + } + } +#endif + + return true; +} + +//======================================================================= +//function : readResultFile +//purpose : +//======================================================================= + +static bool readResultFile(const int fileOpen, +#ifdef WNT + const char* fileName, +#endif + SMESH_Mesh& theMesh, + TopoDS_Shape aSolid, + vector & theNodeByGhs3dId, + int nbEnforcedVertices) +{ + SMESHDS_Mesh* theMeshDS = theMesh.GetMeshDS(); + + Kernel_Utils::Localizer loc; + 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; + + int *tab; + double *coord; + const SMDS_MeshNode **node; + + tab = new int[3]; + coord = new double[3]; + node = new const SMDS_MeshNode*[4]; + + SMDS_MeshNode * aNewNode; + map ::iterator IdNode; + SMDS_MeshElement* aTet; + + // Read the file state + fileStat = fstat(fileOpen, &status); + length = status.st_size; + + // Mapping the result file into memory +#ifdef WNT + HANDLE fd = CreateFile(fileName, 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; + + nbElems = tab[0]; + nbNodes = tab[1]; + nbInputNodes = tab[2]; + + theNodeByGhs3dId.resize( nbNodes ); + + // Reading the nodeId + for (int i=0; i < 4*nbElems; i++) + nodeId = strtol(ptr, &ptr, 10); + + // Issue 0020682. Avoid creating nodes and tetras at place where + // volumic elements already exist + SMESH_ElementSearcher* elemSearcher = 0; + vector< const SMDS_MeshElement* > foundVolumes; + if ( theMesh.NbVolumes() > 0 ) + elemSearcher = SMESH_MeshEditor( &theMesh ).GetElementSearcher(); + + // Reading the nodeCoord and update the nodeMap + shapeID = theMeshDS->ShapeToIndex( aSolid ); + for (int iNode=0; iNode < nbNodes; iNode++) { + for (int iCoor=0; iCoor < 3; iCoor++) + coord[ iCoor ] = strtod(ptr, &ptr); + if ((iNode+1) > (nbInputNodes-nbEnforcedVertices)) { + // Issue 0020682. Avoid creating nodes and tetras at place where + // volumic elements already exist + if ( elemSearcher && + elemSearcher->FindElementsByPoint( gp_Pnt(coord[0],coord[1],coord[2]), + SMDSAbs_Volume, foundVolumes )) + { + theNodeByGhs3dId[ iNode ] = 0; + } + else + { + aNewNode = theMeshDS->AddNode( coord[0],coord[1],coord[2] ); + theMeshDS->SetNodeInVolume( aNewNode, shapeID ); + theNodeByGhs3dId[ iNode ] = aNewNode; + } + } + } + + // Reading the triangles + nbTriangle = strtol(ptr, &ptr, 10); + + for (int i=0; i < 3*nbTriangle; i++) + triangleId = strtol(ptr, &ptr, 10); + + shapePtr = ptr; + + // Associating the tetrahedrons to the shapes + for (int iElem = 0; iElem < nbElems; iElem++) { + for (int iNode = 0; iNode < 4; iNode++) { + ID = strtol(tetraPtr, &tetraPtr, 10); + node[ iNode ] = theNodeByGhs3dId[ ID-1 ]; + } + if ( elemSearcher ) + { + // Issue 0020682. Avoid creating nodes and tetras at place where + // volumic elements already exist + if ( !node[1] || !node[0] || !node[2] || !node[3] ) + continue; + if ( elemSearcher->FindElementsByPoint(( SMESH_TNodeXYZ(node[0]) + + SMESH_TNodeXYZ(node[1]) + + SMESH_TNodeXYZ(node[2]) + + SMESH_TNodeXYZ(node[3]) ) / 4., + SMDSAbs_Volume, foundVolumes )) + continue; + } + aTet = theMeshDS->AddVolume( node[1], node[0], node[2], node[3] ); + shapeID = theMeshDS->ShapeToIndex( aSolid ); + theMeshDS->SetMeshElementOnShape( aTet, shapeID ); + } + if ( nbElems ) + cout << nbElems << " tetrahedrons have been associated to " << nbTriangle << " shapes" << endl; +#ifdef WNT + UnmapViewOfFile(mapPtr); + CloseHandle(hMapObject); + CloseHandle(fd); +#else + munmap(mapPtr, length); +#endif + close(fileOpen); + + delete [] tab; + delete [] coord; + delete [] node; + + return true; +} + +//============================================================================= +/*! + *Here we are going to use the GHS3D mesher + */ +//============================================================================= + +bool GHS3DPlugin_GHS3D::Compute(SMESH_Mesh& theMesh, + const TopoDS_Shape& theShape) +{ + bool Ok(false); + //SMESHDS_Mesh* meshDS = theMesh.GetMeshDS(); + + // we count the number of shapes + // _nbShape = countShape( meshDS, TopAbs_SOLID ); -- 0020330: Pb with ghs3d as a submesh + _nbShape = 0; + TopExp_Explorer expBox ( theShape, TopAbs_SOLID ); + for ( ; expBox.More(); expBox.Next() ) + _nbShape++; + + // 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; + + for (expBox.ReInit(); 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++; + } + + // a unique working file name + // to avoid access to the same files by eg different users + TCollection_AsciiString aGenericName + = (char*) GHS3DPlugin_Hypothesis::GetFileName(_hyp).c_str(); + + 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 = + aFacesFile.rdbuf()->is_open() && aPointsFile.rdbuf()->is_open(); + if (!Ok) { + INFOS( "Can't write into " << aFacesFileName); + return error(SMESH_Comment("Can't write into ") << aFacesFileName); + } + map aSmdsToGhs3dIdMap; + map aGhs3dIdToNodeMap; + map,double> enforcedVertices; + int nbEnforcedVertices = 0; + try { + enforcedVertices = GHS3DPlugin_Hypothesis::GetEnforcedVertices(_hyp); + nbEnforcedVertices = enforcedVertices.size(); + } + catch(...) { + } + + SMESH_MesherHelper helper( theMesh ); + helper.SetSubShape( theShape ); + + { + SMESH_ProxyMesh::Ptr proxyMesh( new SMESH_ProxyMesh( theMesh )); + + // make prisms on quadrangles + if ( theMesh.NbQuadrangles() > 0 ) + { + vector components; + for (expBox.ReInit(); expBox.More(); expBox.Next()) + { + if ( _viscousLayersHyp ) + { + proxyMesh = _viscousLayersHyp->Compute( theMesh, expBox.Current() ); + if ( !proxyMesh ) + return false; + } + StdMeshers_QuadToTriaAdaptor* q2t = new StdMeshers_QuadToTriaAdaptor; + q2t->Compute( theMesh, expBox.Current(), proxyMesh.get() ); + components.push_back( SMESH_ProxyMesh::Ptr( q2t )); + } + proxyMesh.reset( new SMESH_ProxyMesh( components )); + } + // build viscous layers + else if ( _viscousLayersHyp ) + { + proxyMesh = _viscousLayersHyp->Compute( theMesh, theShape ); + if ( !proxyMesh ) + return false; + } + + Ok = (writePoints( aPointsFile, helper, aSmdsToGhs3dIdMap, aGhs3dIdToNodeMap, enforcedVertices) + && + writeFaces ( aFacesFile, *proxyMesh, theShape, aSmdsToGhs3dIdMap )); + } + + // Write aSmdsToGhs3dIdMap to temp file + TCollection_AsciiString aSmdsToGhs3dIdMapFileName; + aSmdsToGhs3dIdMapFileName = aGenericName + ".ids"; // ids relation + ofstream aIdsFile ( aSmdsToGhs3dIdMapFileName.ToCString() , ios::out); + Ok = + aIdsFile.rdbuf()->is_open(); + if (!Ok) { + INFOS( "Can't write into " << aSmdsToGhs3dIdMapFileName); + return error(SMESH_Comment("Can't write into ") << aSmdsToGhs3dIdMapFileName); + } + aIdsFile << "Smds Ghs3d" << std::endl; + map ::const_iterator myit; + for (myit=aSmdsToGhs3dIdMap.begin() ; myit != aSmdsToGhs3dIdMap.end() ; ++myit) { + aIdsFile << myit->first << " " << myit->second << std::endl; + } + + aFacesFile.close(); + aPointsFile.close(); + aIdsFile.close(); + + if ( ! Ok ) { + if ( !_keepFiles ) { + removeFile( aFacesFileName ); + removeFile( aPointsFileName ); + removeFile( aSmdsToGhs3dIdMapFileName ); + } + return error(COMPERR_BAD_INPUT_MESH); + } + removeFile( aResultFileName ); // needed for boundary recovery module usage + + // ----------------- + // run ghs3d mesher + // ----------------- + + TCollection_AsciiString cmd( (char*)GHS3DPlugin_Hypothesis::CommandToRun( _hyp ).c_str() ); + cmd += TCollection_AsciiString(" -f ") + aGenericName; // file to read + cmd += TCollection_AsciiString(" 1>" ) + aLogFileName; // dump into file + + std::cout << std::endl; + std::cout << "Ghs3d execution..." << std::endl; + std::cout << cmd << std::endl; + + system( cmd.ToCString() ); // run + + std::cout << std::endl; + std::cout << "End of Ghs3d execution !" << std::endl; + + // -------------- + // read a result + // -------------- + + // Mapping the result file + + int fileOpen; + 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 { + bool toMeshHoles = + _hyp ? _hyp->GetToMeshHoles(true) : GHS3DPlugin_Hypothesis::DefaultMeshHoles(); + Ok = readResultFile( fileOpen, +#ifdef WNT + aResultFileName.ToCString(), +#endif + theMesh, tabShape, tabBox, _nbShape, aGhs3dIdToNodeMap, + toMeshHoles, nbEnforcedVertices ); + } + + // --------------------- + // remove working files + // --------------------- + + if ( Ok ) + { + if ( !_keepFiles ) + removeFile( aLogFileName ); + } + else if ( OSD_File( aLogFileName ).Size() > 0 ) + { + // get problem description from the log file + _Ghs2smdsConvertor conv( aGhs3dIdToNodeMap ); + storeErrorDescription( aLogFileName, conv ); + } + else + { + // the log file is empty + removeFile( aLogFileName ); + INFOS( "GHS3D Error, command '" << cmd.ToCString() << "' failed" ); + error(COMPERR_ALGO_FAILED, "ghs3d: command not found" ); + } + + if ( !_keepFiles ) { + removeFile( aFacesFileName ); + removeFile( aPointsFileName ); + removeFile( aResultFileName ); + removeFile( aBadResFileName ); + removeFile( aBbResFileName ); + removeFile( aSmdsToGhs3dIdMapFileName ); + } + std::cout << "<" << aResultFileName.ToCString() << "> GHS3D output file "; + if ( !Ok ) + std::cout << "not "; + std::cout << "treated !" << std::endl; + std::cout << std::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(); + + // a unique working file name + // to avoid access to the same files by eg different users + TCollection_AsciiString aGenericName + = (char*) GHS3DPlugin_Hypothesis::GetFileName(_hyp).c_str(); + + 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 = + aFacesFile.rdbuf()->is_open() && aPointsFile.rdbuf()->is_open(); + + if (!Ok) + return error( SMESH_Comment("Can't write into ") << aPointsFileName); + + GHS3DPlugin_Hypothesis::TEnforcedVertexValues enforcedVertices; + int nbEnforcedVertices = 0; + try { + enforcedVertices = GHS3DPlugin_Hypothesis::GetEnforcedVertices(_hyp); + nbEnforcedVertices = enforcedVertices.size(); + } + catch(...) { + } + + vector aNodeByGhs3dId; + { + SMESH_ProxyMesh::Ptr proxyMesh( new SMESH_ProxyMesh( theMesh )); + if ( theMesh.NbQuadrangles() > 0 ) + { + StdMeshers_QuadToTriaAdaptor* aQuad2Trias = new StdMeshers_QuadToTriaAdaptor; + aQuad2Trias->Compute( theMesh ); + proxyMesh.reset( aQuad2Trias ); + } + + Ok = (writeFaces ( aFacesFile, *proxyMesh, aNodeByGhs3dId ) && + writePoints( aPointsFile, &theMesh, aNodeByGhs3dId,enforcedVertices)); + } + aFacesFile.close(); + aPointsFile.close(); + + if ( ! Ok ) { + if ( !_keepFiles ) { + removeFile( aFacesFileName ); + removeFile( aPointsFileName ); + } + return error(COMPERR_BAD_INPUT_MESH); + } + removeFile( aResultFileName ); // needed for boundary recovery module usage + + // ----------------- + // run ghs3d mesher + // ----------------- + + TCollection_AsciiString cmd = + (char*)GHS3DPlugin_Hypothesis::CommandToRun( _hyp, false ).c_str(); + cmd += TCollection_AsciiString(" -f ") + aGenericName; // file to read + cmd += TCollection_AsciiString(" 1>" ) + aLogFileName; // dump into file + + system( cmd.ToCString() ); // run + + // -------------- + // read a result + // -------------- + int fileOpen; + fileOpen = open( aResultFileName.ToCString(), O_RDONLY); + if ( fileOpen < 0 ) { + std::cout << std::endl; + std::cout << "Error when opening the " << aResultFileName.ToCString() << " file" << std::endl; + std::cout << "Log: " << aLogFileName << std::endl; + std::cout << std::endl; + Ok = false; + } + else { + Ok = readResultFile( fileOpen, +#ifdef WNT + aResultFileName.ToCString(), +#endif + theMesh, theShape ,aNodeByGhs3dId, nbEnforcedVertices ); + } + + // --------------------- + // remove working files + // --------------------- + + if ( Ok ) + { + if ( !_keepFiles ) + removeFile( aLogFileName ); + } + else if ( OSD_File( aLogFileName ).Size() > 0 ) + { + // get problem description from the log file + _Ghs2smdsConvertor conv( aNodeByGhs3dId ); + storeErrorDescription( aLogFileName, conv ); + } + else { + // the log file is empty + removeFile( aLogFileName ); + INFOS( "GHS3D Error, command '" << cmd.ToCString() << "' failed" ); + error(COMPERR_ALGO_FAILED, "ghs3d: command not found" ); + } + + if ( !_keepFiles ) + { + removeFile( aFacesFileName ); + removeFile( aPointsFileName ); + removeFile( aResultFileName ); + removeFile( aBadResFileName ); + removeFile( aBbResFileName ); + } + + return Ok; +} + +//================================================================================ +/*! + * \brief Provide human readable text by error code reported by ghs3d + */ +//================================================================================ + +static string translateError(const int errNum) +{ + switch ( errNum ) { + case 0: + return "The surface mesh includes a face of type other than edge, " + "triangle or quadrilateral. This face type is not supported."; + case 1: + return "Not enough memory for the face table."; + case 2: + return "Not enough memory."; + case 3: + return "Not enough memory."; + case 4: + return "Face is ignored."; + case 5: + return "End of file. Some data are missing in the file."; + case 6: + return "Read error on the file. There are wrong data in the file."; + case 7: + return "the metric file is inadequate (dimension other than 3)."; + case 8: + return "the metric file is inadequate (values not per vertices)."; + case 9: + return "the metric file contains more than one field."; + case 10: + return "the number of values in the \".bb\" (metric file) is incompatible with the expected" + "value of number of mesh vertices in the \".noboite\" file."; + case 12: + return "Too many sub-domains."; + case 13: + return "the number of vertices is negative or null."; + case 14: + return "the number of faces is negative or null."; + case 15: + return "A face has a null vertex."; + case 22: + return "incompatible data."; + case 131: + return "the number of vertices is negative or null."; + case 132: + return "the number of vertices is negative or null (in the \".mesh\" file)."; + case 133: + return "the number of faces is negative or null."; + case 1000: + return "A face appears more than once in the input surface mesh."; + case 1001: + return "An edge appears more than once in the input surface mesh."; + case 1002: + return "A face has a vertex negative or null."; + case 1003: + return "NOT ENOUGH MEMORY."; + case 2000: + return "Not enough available memory."; + case 2002: + return "Some initial points cannot be inserted. The surface mesh is probably very bad " + "in terms of quality or the input list of points is wrong."; + case 2003: + return "Some vertices are too close to one another or coincident."; + case 2004: + return "Some vertices are too close to one another or coincident."; + case 2012: + return "A vertex cannot be inserted."; + case 2014: + return "There are at least two points considered as coincident."; + case 2103: + return "Some vertices are too close to one another or coincident."; + case 3000: + return "The surface mesh regeneration step has failed."; + case 3009: + return "Constrained edge cannot be enforced."; + case 3019: + return "Constrained face cannot be enforced."; + case 3029: + return "Missing faces."; + case 3100: + return "No guess to start the definition of the connected component(s)."; + case 3101: + return "The surface mesh includes at least one hole. The domain is not well defined."; + case 3102: + return "Impossible to define a component."; + case 3103: + return "The surface edge intersects another surface edge."; + case 3104: + return "The surface edge intersects the surface face."; + case 3105: + return "One boundary point lies within a surface face."; + case 3106: + return "One surface edge intersects a surface face."; + case 3107: + return "One boundary point lies within a surface edge."; + case 3108: + return "Insufficient memory ressources detected due to a bad quality surface mesh leading " + "to too many swaps."; + case 3109: + return "Edge is unique (i.e., bounds a hole in the surface)."; + case 3122: + return "Presumably, the surface mesh is not compatible with the domain being processed."; + case 3123: + return "Too many components, too many sub-domain."; + case 3209: + return "The surface mesh includes at least one hole. " + "Therefore there is no domain properly defined."; + case 3300: + return "Statistics."; + case 3400: + return "Statistics."; + case 3500: + return "Warning, it is dramatically tedious to enforce the boundary items."; + case 4000: + return "Not enough memory at this time, nevertheless, the program continues. " + "The expected mesh will be correct but not really as large as required."; + case 4002: + return "see above error code, resulting quality may be poor."; + case 4003: + return "Not enough memory at this time, nevertheless, the program continues (warning)."; + case 8000: + return "Unknown face type."; + case 8005: + case 8006: + return "End of file. Some data are missing in the file."; + case 9000: + return "A too small volume element is detected."; + case 9001: + return "There exists at least a null or negative volume element."; + case 9002: + return "There exist null or negative volume elements."; + case 9003: + return "A too small volume element is detected. A face is considered being degenerated."; + case 9100: + return "Some element is suspected to be very bad shaped or wrong."; + case 9102: + return "A too bad quality face is detected. This face is considered degenerated."; + case 9112: + return "A too bad quality face is detected. This face is degenerated."; + case 9122: + return "Presumably, the surface mesh is not compatible with the domain being processed."; + case 9999: + return "Abnormal error occured, contact hotline."; + case 23600: + return "Not enough memory for the face table."; + case 23601: + return "The algorithm cannot run further. " + "The surface mesh is probably very bad in terms of quality."; + case 23602: + return "Bad vertex number."; + } + return ""; +} + +//================================================================================ +/*! + * \brief Retrieve from a string given number of integers + */ +//================================================================================ + +static char* getIds( char* ptr, int nbIds, vector& ids ) +{ + ids.clear(); + ids.reserve( nbIds ); + while ( nbIds ) + { + while ( !isdigit( *ptr )) ++ptr; + if ( ptr[-1] == '-' ) --ptr; + ids.push_back( strtol( ptr, &ptr, 10 )); + --nbIds; + } + return ptr; +} + +//================================================================================ +/*! + * \brief Retrieve problem description form a log file + * \retval bool - always false + */ +//================================================================================ + +bool GHS3DPlugin_GHS3D::storeErrorDescription(const TCollection_AsciiString& logFile, + const _Ghs2smdsConvertor & toSmdsConvertor ) +{ + // open file +#ifdef WNT + int file = ::_open (logFile.ToCString(), _O_RDONLY|_O_BINARY); +#else + int file = ::open (logFile.ToCString(), O_RDONLY); +#endif + if ( file < 0 ) + return error( SMESH_Comment("See ") << logFile << " for problem description"); + + // get file size +// struct stat status; +// fstat(file, &status); +// size_t length = status.st_size; + off_t length = lseek( file, 0, SEEK_END); + lseek( file, 0, SEEK_SET); + + // read file + vector< char > buf( length ); + int nBytesRead = ::read (file, & buf[0], length); + ::close (file); + char* ptr = & buf[0]; + char* bufEnd = ptr + nBytesRead; + + SMESH_Comment errDescription; + + enum { NODE = 1, EDGE, TRIA, VOL, ID = 1 }; + + // look for errors "ERR #" + + set foundErrorStr; // to avoid reporting same error several times + set elemErrorNums; // not to report different types of errors with bad elements + while ( ++ptr < bufEnd ) + { + if ( strncmp( ptr, "ERR ", 4 ) != 0 ) + continue; + + list badElems; + vector nodeIds; + + ptr += 4; + char* errBeg = ptr; + int errNum = strtol(ptr, &ptr, 10); + switch ( errNum ) { // we treat errors enumerated in [SALOME platform 0019316] issue + case 0015: + // The face number (numfac) with vertices (f 1, f 2, f 3) has a null vertex. + ptr = getIds(ptr, NODE, nodeIds); + ptr = getIds(ptr, TRIA, nodeIds); + badElems.push_back( toSmdsConvertor.getElement(nodeIds)); + break; + case 1000: // ERR 1000 : 1 3 2 + // Face (f 1, f 2, f 3) appears more than once in the input surface mesh. + ptr = getIds(ptr, TRIA, nodeIds); + badElems.push_back( toSmdsConvertor.getElement(nodeIds)); + break; + case 1001: + // Edge (e1, e2) appears more than once in the input surface mesh + ptr = getIds(ptr, EDGE, nodeIds); + badElems.push_back( toSmdsConvertor.getElement(nodeIds)); + break; + case 1002: + // Face (f 1, f 2, f 3) has a vertex negative or null + ptr = getIds(ptr, TRIA, nodeIds); + badElems.push_back( toSmdsConvertor.getElement(nodeIds)); + break; + case 2004: + // Vertex v1 and vertex v2 are too close to one another or coincident (warning). + ptr = getIds(ptr, NODE, nodeIds); + badElems.push_back( toSmdsConvertor.getElement(nodeIds)); + ptr = getIds(ptr, NODE, nodeIds); + badElems.push_back( toSmdsConvertor.getElement(nodeIds)); + break; + case 2012: + // Vertex v1 cannot be inserted (warning). + ptr = getIds(ptr, NODE, nodeIds); + badElems.push_back( toSmdsConvertor.getElement(nodeIds)); + break; + case 2014: + // There are at least two points whose distance is dist, i.e., considered as coincident + case 2103: // ERR 2103 : 16 WITH 3 + // Vertex v1 and vertex v2 are too close to one another or coincident (warning). + ptr = getIds(ptr, NODE, nodeIds); + badElems.push_back( toSmdsConvertor.getElement(nodeIds)); + ptr = getIds(ptr, NODE, nodeIds); + badElems.push_back( toSmdsConvertor.getElement(nodeIds)); + break; + case 3009: + // Constrained edge (e1, e2) cannot be enforced (warning). + ptr = getIds(ptr, EDGE, nodeIds); + badElems.push_back( toSmdsConvertor.getElement(nodeIds)); + break; + case 3019: + // Constrained face (f 1, f 2, f 3) cannot be enforced + ptr = getIds(ptr, TRIA, nodeIds); + badElems.push_back( toSmdsConvertor.getElement(nodeIds)); + break; + case 3103: // ERR 3103 : 1 2 WITH 7 3 + // The surface edge (e1, e2) intersects another surface edge (e3, e4) + ptr = getIds(ptr, EDGE, nodeIds); + badElems.push_back( toSmdsConvertor.getElement(nodeIds)); + ptr = getIds(ptr, EDGE, nodeIds); + badElems.push_back( toSmdsConvertor.getElement(nodeIds)); + break; + case 3104: // ERR 3104 : 9 10 WITH 1 2 3 + // The surface edge (e1, e2) intersects the surface face (f 1, f 2, f 3) + ptr = getIds(ptr, EDGE, nodeIds); + badElems.push_back( toSmdsConvertor.getElement(nodeIds)); + ptr = getIds(ptr, TRIA, nodeIds); + badElems.push_back( toSmdsConvertor.getElement(nodeIds)); + break; + case 3105: // ERR 3105 : 8 IN 2 3 5 + // One boundary point (say p1) lies within a surface face (f 1, f 2, f 3) + ptr = getIds(ptr, NODE, nodeIds); + badElems.push_back( toSmdsConvertor.getElement(nodeIds)); + ptr = getIds(ptr, TRIA, nodeIds); + badElems.push_back( toSmdsConvertor.getElement(nodeIds)); + break; + case 3106: + // One surface edge (say e1, e2) intersects a surface face (f 1, f 2, f 3) + ptr = getIds(ptr, EDGE, nodeIds); + badElems.push_back( toSmdsConvertor.getElement(nodeIds)); + ptr = getIds(ptr, TRIA, nodeIds); + badElems.push_back( toSmdsConvertor.getElement(nodeIds)); + break; + case 3107: // ERR 3107 : 2 IN 4 1 + // One boundary point (say p1) lies within a surface edge (e1, e2) (stop). + ptr = getIds(ptr, NODE, nodeIds); + badElems.push_back( toSmdsConvertor.getElement(nodeIds)); + ptr = getIds(ptr, EDGE, nodeIds); + badElems.push_back( toSmdsConvertor.getElement(nodeIds)); + break; + case 3109: // ERR 3109 : EDGE 5 6 UNIQUE + // Edge (e1, e2) is unique (i.e., bounds a hole in the surface) + ptr = getIds(ptr, EDGE, nodeIds); + badElems.push_back( toSmdsConvertor.getElement(nodeIds)); + break; + case 9000: // ERR 9000 + // ELEMENT 261 WITH VERTICES : 7 396 -8 242 + // VOLUME : -1.11325045E+11 W.R.T. EPSILON 0. + // A too small volume element is detected. Are reported the index of the element, + // its four vertex indices, its volume and the tolerance threshold value + ptr = getIds(ptr, ID, nodeIds); + ptr = getIds(ptr, VOL, nodeIds); + badElems.push_back( toSmdsConvertor.getElement(nodeIds)); + // even if all nodes found, volume it most probably invisible, + // add its faces to demenstrate it anyhow + { + vector faceNodes( nodeIds.begin(), --nodeIds.end() ); // 012 + badElems.push_back( toSmdsConvertor.getElement(faceNodes)); + faceNodes[2] = nodeIds[3]; // 013 + badElems.push_back( toSmdsConvertor.getElement(faceNodes)); + faceNodes[1] = nodeIds[2]; // 023 + badElems.push_back( toSmdsConvertor.getElement(faceNodes)); + faceNodes[0] = nodeIds[1]; // 123 + badElems.push_back( toSmdsConvertor.getElement(faceNodes)); + } + break; + case 9001: // ERR 9001 + // %% NUMBER OF NEGATIVE VOLUME TETS : 1 + // %% THE LARGEST NEGATIVE TET : 1.75376581E+11 + // %% NUMBER OF NULL VOLUME TETS : 0 + // There exists at least a null or negative volume element + break; + case 9002: + // There exist n null or negative volume elements + break; + case 9003: + // A too small volume element is detected + break; + case 9102: + // A too bad quality face is detected. This face is considered degenerated, + // its index, its three vertex indices together with its quality value are reported + break; // same as next + case 9112: // ERR 9112 + // FACE 2 WITH VERTICES : 4 2 5 + // SMALL INRADIUS : 0. + // A too bad quality face is detected. This face is degenerated, + // its index, its three vertex indices together with its inradius are reported + ptr = getIds(ptr, ID, nodeIds); + ptr = getIds(ptr, TRIA, nodeIds); + badElems.push_back( toSmdsConvertor.getElement(nodeIds)); + // add triangle edges as it most probably has zero area and hence invisible + { + vector edgeNodes(2); + edgeNodes[0] = nodeIds[0]; edgeNodes[1] = nodeIds[1]; // 0-1 + badElems.push_back( toSmdsConvertor.getElement(edgeNodes)); + edgeNodes[1] = nodeIds[2]; // 0-2 + badElems.push_back( toSmdsConvertor.getElement(edgeNodes)); + edgeNodes[0] = nodeIds[1]; // 1-2 + badElems.push_back( toSmdsConvertor.getElement(edgeNodes)); + } + break; + } + + bool isNewError = foundErrorStr.insert( string( errBeg, ptr )).second; + if ( !isNewError ) + continue; // not to report same error several times + +// const SMDS_MeshElement* nullElem = 0; +// bool allElemsOk = ( find( badElems.begin(), badElems.end(), nullElem) == badElems.end()); + +// if ( allElemsOk && !badElems.empty() && !elemErrorNums.empty() ) { +// bool oneMoreErrorType = elemErrorNums.insert( errNum ).second; +// if ( oneMoreErrorType ) +// continue; // not to report different types of errors with bad elements +// } + + // store bad elements + //if ( allElemsOk ) { + list::iterator elem = badElems.begin(); + for ( ; elem != badElems.end(); ++elem ) + addBadInputElement( *elem ); + //} + + // make error text + string text = translateError( errNum ); + if ( errDescription.find( text ) == text.npos ) { + if ( !errDescription.empty() ) + errDescription << "\n"; + errDescription << text; + } + + } // end while + + if ( errDescription.empty() ) { // no errors found + char msg[] = "connection to server failed"; + if ( search( &buf[0], bufEnd, msg, msg + strlen(msg)) != bufEnd ) + errDescription << "Licence problems."; + else + { + char msg2[] = "SEGMENTATION FAULT"; + if ( search( &buf[0], bufEnd, msg2, msg2 + strlen(msg2)) != bufEnd ) + errDescription << "ghs3d: SEGMENTATION FAULT. "; + } + } + + if ( errDescription.empty() ) + errDescription << "See " << logFile << " for problem description"; + else + errDescription << "\nSee " << logFile << " for more information"; + + return error( errDescription ); +} + +//================================================================================ +/*! + * \brief Creates _Ghs2smdsConvertor + */ +//================================================================================ + +_Ghs2smdsConvertor::_Ghs2smdsConvertor( const map & ghs2NodeMap) + :_ghs2NodeMap( & ghs2NodeMap ), _nodeByGhsId( 0 ) +{ +} + +//================================================================================ +/*! + * \brief Creates _Ghs2smdsConvertor + */ +//================================================================================ + +_Ghs2smdsConvertor::_Ghs2smdsConvertor( const vector & nodeByGhsId) + : _ghs2NodeMap( 0 ), _nodeByGhsId( &nodeByGhsId ) +{ +} + +//================================================================================ +/*! + * \brief Return SMDS element by ids of GHS3D nodes + */ +//================================================================================ + +const SMDS_MeshElement* _Ghs2smdsConvertor::getElement(const vector& ghsNodes) const +{ + size_t nbNodes = ghsNodes.size(); + vector nodes( nbNodes, 0 ); + for ( size_t i = 0; i < nbNodes; ++i ) { + int ghsNode = ghsNodes[ i ]; + if ( _ghs2NodeMap ) { + map ::const_iterator in = _ghs2NodeMap->find( ghsNode); + if ( in == _ghs2NodeMap->end() ) + return 0; + nodes[ i ] = in->second; + } + else { + if ( ghsNode < 1 || ghsNode > _nodeByGhsId->size() ) + return 0; + nodes[ i ] = (*_nodeByGhsId)[ ghsNode-1 ]; + } + } + if ( nbNodes == 1 ) + return nodes[0]; + + if ( nbNodes == 2 ) { + const SMDS_MeshElement* edge= SMDS_Mesh::FindEdge( nodes[0], nodes[1] ); + if ( !edge ) + edge = new SMDS_LinearEdge( nodes[0], nodes[1] ); + return edge; + } + if ( nbNodes == 3 ) { + const SMDS_MeshElement* face = SMDS_Mesh::FindFace( nodes ); + if ( !face ) + face = new SMDS_FaceOfNodes( nodes[0], nodes[1], nodes[2] ); + return face; + } + if ( nbNodes == 4 ) + return new SMDS_VolumeOfNodes( nodes[0], nodes[1], nodes[2], nodes[3] ); + + return 0; +} + + +//============================================================================= +/*! + * + */ +//============================================================================= +bool GHS3DPlugin_GHS3D::Evaluate(SMESH_Mesh& aMesh, + const TopoDS_Shape& aShape, + MapShapeNbElems& aResMap) +{ + int nbtri = 0, nbqua = 0; + double fullArea = 0.0; + for (TopExp_Explorer exp(aShape, TopAbs_FACE); exp.More(); exp.Next()) { + TopoDS_Face F = TopoDS::Face( exp.Current() ); + SMESH_subMesh *sm = aMesh.GetSubMesh(F); + MapShapeNbElemsItr anIt = aResMap.find(sm); + if( anIt==aResMap.end() ) { + SMESH_ComputeErrorPtr& smError = sm->GetComputeError(); + smError.reset( new SMESH_ComputeError(COMPERR_ALGO_FAILED, + "Submesh can not be evaluated",this)); + return false; + } + std::vector aVec = (*anIt).second; + nbtri += Max(aVec[SMDSEntity_Triangle],aVec[SMDSEntity_Quad_Triangle]); + nbqua += Max(aVec[SMDSEntity_Quadrangle],aVec[SMDSEntity_Quad_Quadrangle]); + GProp_GProps G; + BRepGProp::SurfaceProperties(F,G); + double anArea = G.Mass(); + fullArea += anArea; + } + + // collect info from edges + int nb0d_e = 0, nb1d_e = 0; + bool IsQuadratic = false; + bool IsFirst = true; + TopTools_MapOfShape tmpMap; + for (TopExp_Explorer exp(aShape, TopAbs_EDGE); exp.More(); exp.Next()) { + TopoDS_Edge E = TopoDS::Edge(exp.Current()); + if( tmpMap.Contains(E) ) + continue; + tmpMap.Add(E); + SMESH_subMesh *aSubMesh = aMesh.GetSubMesh(exp.Current()); + MapShapeNbElemsItr anIt = aResMap.find(aSubMesh); + std::vector aVec = (*anIt).second; + nb0d_e += aVec[SMDSEntity_Node]; + nb1d_e += Max(aVec[SMDSEntity_Edge],aVec[SMDSEntity_Quad_Edge]); + if(IsFirst) { + IsQuadratic = (aVec[SMDSEntity_Quad_Edge] > aVec[SMDSEntity_Edge]); + IsFirst = false; + } + } + tmpMap.Clear(); + + double ELen = sqrt(2.* ( fullArea/(nbtri+nbqua*2) ) / sqrt(3.0) ); + + GProp_GProps G; + BRepGProp::VolumeProperties(aShape,G); + double aVolume = G.Mass(); + double tetrVol = 0.1179*ELen*ELen*ELen; + double CoeffQuality = 0.9; + int nbVols = int(aVolume/tetrVol/CoeffQuality); + int nb1d_f = (nbtri*3 + nbqua*4 - nb1d_e) / 2; + int nb1d_in = (int) ( nbVols*6 - nb1d_e - nb1d_f ) / 5; + std::vector aVec(SMDSEntity_Last); + for(int i=SMDSEntity_Node; i +#include + +class GHS3DPlugin_Hypothesis; +class SMDS_MeshNode; +class SMESH_Mesh; +class StdMeshers_ViscousLayers; +class TCollection_AsciiString; +class _Ghs2smdsConvertor; + +class GHS3DPlugin_GHS3D: public SMESH_3D_Algo +{ +public: + GHS3DPlugin_GHS3D(int hypId, int studyId, SMESH_Gen* gen); + virtual ~GHS3DPlugin_GHS3D(); + + virtual bool CheckHypothesis(SMESH_Mesh& aMesh, + const TopoDS_Shape& aShape, + Hypothesis_Status& aStatus); + + virtual bool Compute(SMESH_Mesh& aMesh, + const TopoDS_Shape& aShape); + + virtual bool Evaluate(SMESH_Mesh& aMesh, const TopoDS_Shape& aShape, + MapShapeNbElems& aResMap); + + virtual bool Compute(SMESH_Mesh& theMesh, + SMESH_MesherHelper* aHelper); + +private: + + bool storeErrorDescription(const TCollection_AsciiString& logFile, + const _Ghs2smdsConvertor & toSmdsConvertor ); + + int _iShape; + int _nbShape; + bool _keepFiles; + const GHS3DPlugin_Hypothesis* _hyp; + const StdMeshers_ViscousLayers* _viscousLayersHyp; +}; + +/*! + * \brief Convertor of GHS3D elements to SMDS ones + */ +class _Ghs2smdsConvertor +{ + const std::map * _ghs2NodeMap; + const std::vector * _nodeByGhsId; + +public: + _Ghs2smdsConvertor( const std::map & ghs2NodeMap); + + _Ghs2smdsConvertor( const std::vector & nodeByGhsId); + + const SMDS_MeshElement* getElement(const std::vector& ghsNodes) const; +}; + +#endif diff --git a/src/GHS3DPlugin/GHS3DPlugin_GHS3D_i.cxx b/src/GHS3DPlugin/GHS3DPlugin_GHS3D_i.cxx new file mode 100644 index 0000000..c63525a --- /dev/null +++ b/src/GHS3DPlugin/GHS3DPlugin_GHS3D_i.cxx @@ -0,0 +1,82 @@ +// Copyright (C) 2004-2010 CEA/DEN, EDF R&D +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +// SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses +// File : GHS3DPlugin_GHS3D_i.cxx +// Author : Edward AGAPOV +// Module : GHS3DPlugin +// $Header$ +// +#include "GHS3DPlugin_GHS3D_i.hxx" +#include "SMESH_Gen.hxx" +#include "GHS3DPlugin_GHS3D.hxx" + +#include "utilities.h" + +using namespace std; + +//============================================================================= +/*! + * GHS3DPlugin_GHS3D_i::GHS3DPlugin_GHS3D_i + * + * Constructor + */ +//============================================================================= + +GHS3DPlugin_GHS3D_i::GHS3DPlugin_GHS3D_i (PortableServer::POA_ptr thePOA, + int theStudyId, + ::SMESH_Gen* theGenImpl ) + : SALOME::GenericObj_i( thePOA ), + SMESH_Hypothesis_i( thePOA ), + SMESH_Algo_i( thePOA ), + SMESH_3D_Algo_i( thePOA ) +{ + MESSAGE( "GHS3DPlugin_GHS3D_i::GHS3DPlugin_GHS3D_i" ); + myBaseImpl = new ::GHS3DPlugin_GHS3D (theGenImpl->GetANewId(), + theStudyId, + theGenImpl ); +} + +//============================================================================= +/*! + * GHS3DPlugin_GHS3D_i::~GHS3DPlugin_GHS3D_i + * + * Destructor + */ +//============================================================================= + +GHS3DPlugin_GHS3D_i::~GHS3DPlugin_GHS3D_i() +{ + MESSAGE( "GHS3DPlugin_GHS3D_i::~GHS3DPlugin_GHS3D_i" ); +} + +//============================================================================= +/*! + * GHS3DPlugin_GHS3D_i::GetImpl + * + * Get implementation + */ +//============================================================================= + +::GHS3DPlugin_GHS3D* GHS3DPlugin_GHS3D_i::GetImpl() +{ + MESSAGE( "GHS3DPlugin_GHS3D_i::GetImpl" ); + return ( ::GHS3DPlugin_GHS3D* )myBaseImpl; +} + diff --git a/src/GHS3DPlugin/GHS3DPlugin_GHS3D_i.hxx b/src/GHS3DPlugin/GHS3DPlugin_GHS3D_i.hxx new file mode 100644 index 0000000..e61fb45 --- /dev/null +++ b/src/GHS3DPlugin/GHS3DPlugin_GHS3D_i.hxx @@ -0,0 +1,54 @@ +// Copyright (C) 2004-2010 CEA/DEN, EDF R&D +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +// File : GHS3DPlugin_GHS3D_i.hxx +// Author : Edward AGAPOV +// Module : GHS3DPlugin +// $Header$ +// +#ifndef _GHS3DPlugin_GHS3D_I_HXX_ +#define _GHS3DPlugin_GHS3D_I_HXX_ + +#include +#include CORBA_SERVER_HEADER(GHS3DPlugin_Algorithm) +#include CORBA_SERVER_HEADER(SALOME_Exception) + +#include "SMESH_3D_Algo_i.hxx" +#include "GHS3DPlugin_GHS3D.hxx" + +// ====================================================== +// GHS3D 3d algorithm +// ====================================================== +class GHS3DPlugin_GHS3D_i: + public virtual POA_GHS3DPlugin::GHS3DPlugin_GHS3D, + public virtual SMESH_3D_Algo_i +{ +public: + // Constructor + GHS3DPlugin_GHS3D_i (PortableServer::POA_ptr thePOA, + int theStudyId, + ::SMESH_Gen* theGenImpl ); + // Destructor + virtual ~GHS3DPlugin_GHS3D_i(); + + // Get implementation + ::GHS3DPlugin_GHS3D* GetImpl(); +}; + +#endif diff --git a/src/GHS3DPlugin/GHS3DPlugin_Hypothesis.cxx b/src/GHS3DPlugin/GHS3DPlugin_Hypothesis.cxx new file mode 100644 index 0000000..bdfa2b9 --- /dev/null +++ b/src/GHS3DPlugin/GHS3DPlugin_Hypothesis.cxx @@ -0,0 +1,883 @@ +// Copyright (C) 2004-2010 CEA/DEN, EDF R&D +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +//============================================================================= +// File : GHS3DPlugin_Hypothesis.cxx +// Created : Wed Apr 2 12:36:29 2008 +// Author : Edward AGAPOV (eap) +//============================================================================= +// +#include "GHS3DPlugin_Hypothesis.hxx" + +#include + +#ifdef WNT +#include +#define getpid _getpid +#endif + +//======================================================================= +//function : GHS3DPlugin_Hypothesis +//======================================================================= + +GHS3DPlugin_Hypothesis::GHS3DPlugin_Hypothesis(int hypId, int studyId, SMESH_Gen * gen) + : SMESH_Hypothesis(hypId, studyId, gen), + myToMeshHoles(DefaultMeshHoles()), + myMaximumMemory(-1), + myInitialMemory(-1), + myOptimizationLevel(DefaultOptimizationLevel()), + myWorkingDirectory(DefaultWorkingDirectory()), + myKeepFiles(DefaultKeepFiles()), + myVerboseLevel(DefaultVerboseLevel()), + myToCreateNewNodes(DefaultToCreateNewNodes()), + myToUseBoundaryRecoveryVersion(DefaultToUseBoundaryRecoveryVersion()), + myToUseFemCorrection(DefaultToUseFEMCorrection()), + myToRemoveCentralPoint(DefaultToRemoveCentralPoint()), + myEnforcedVertices(DefaultEnforcedVertices()) +{ + _name = "GHS3D_Parameters"; + _param_algo_dim = 3; +} + +//======================================================================= +//function : SetToMeshHoles +//======================================================================= + +void GHS3DPlugin_Hypothesis::SetToMeshHoles(bool toMesh) +{ + if ( myToMeshHoles != toMesh ) { + myToMeshHoles = toMesh; + NotifySubMeshesHypothesisModification(); + } +} + +//======================================================================= +//function : GetToMeshHoles +//======================================================================= + +bool GHS3DPlugin_Hypothesis::GetToMeshHoles(bool checkFreeOption) const +{ + if (checkFreeOption && !myTextOption.empty()) { + if ( myTextOption.find("-c 0")) + return true; + if ( myTextOption.find("-c 1")) + return false; + } + return myToMeshHoles; +} + +//======================================================================= +//function : SetMaximumMemory +//======================================================================= + +void GHS3DPlugin_Hypothesis::SetMaximumMemory(short MB) +{ + if ( myMaximumMemory != MB ) { + myMaximumMemory = MB; + NotifySubMeshesHypothesisModification(); + } +} + +//======================================================================= +//function : GetMaximumMemory +// * automatic memory adjustment mode. Default is zero +//======================================================================= + +short GHS3DPlugin_Hypothesis::GetMaximumMemory() const +{ + return myMaximumMemory; +} + +//======================================================================= +//function : SetInitialMemory +//======================================================================= + +void GHS3DPlugin_Hypothesis::SetInitialMemory(short MB) +{ + if ( myInitialMemory != MB ) { + myInitialMemory = MB; + NotifySubMeshesHypothesisModification(); + } +} + +//======================================================================= +//function : GetInitialMemory +//======================================================================= + +short GHS3DPlugin_Hypothesis::GetInitialMemory() const +{ + return myInitialMemory; +} + +//======================================================================= +//function : SetOptimizationLevel +//======================================================================= + +void GHS3DPlugin_Hypothesis::SetOptimizationLevel(OptimizationLevel level) +{ + if ( myOptimizationLevel != level ) { + myOptimizationLevel = level; + NotifySubMeshesHypothesisModification(); + } +} + +//======================================================================= +//function : GetOptimizationLevel +//======================================================================= + +GHS3DPlugin_Hypothesis::OptimizationLevel GHS3DPlugin_Hypothesis::GetOptimizationLevel() const +{ + return (OptimizationLevel) myOptimizationLevel; +} + +//======================================================================= +//function : SetWorkingDirectory +//======================================================================= + +void GHS3DPlugin_Hypothesis::SetWorkingDirectory(const std::string& path) +{ + if ( myWorkingDirectory != path ) { + myWorkingDirectory = path; + NotifySubMeshesHypothesisModification(); + } +} + +//======================================================================= +//function : GetWorkingDirectory +//======================================================================= + +std::string GHS3DPlugin_Hypothesis::GetWorkingDirectory() const +{ + return myWorkingDirectory; +} + +//======================================================================= +//function : SetKeepFiles +//======================================================================= + +void GHS3DPlugin_Hypothesis::SetKeepFiles(bool toKeep) +{ + if ( myKeepFiles != toKeep ) { + myKeepFiles = toKeep; + NotifySubMeshesHypothesisModification(); + } +} + +//======================================================================= +//function : GetKeepFiles +//======================================================================= + +bool GHS3DPlugin_Hypothesis::GetKeepFiles() const +{ + return myKeepFiles; +} + +//======================================================================= +//function : SetVerboseLevel +//======================================================================= + +void GHS3DPlugin_Hypothesis::SetVerboseLevel(short level) +{ + if ( myVerboseLevel != level ) { + myVerboseLevel = level; + NotifySubMeshesHypothesisModification(); + } +} + +//======================================================================= +//function : GetVerboseLevel +//======================================================================= + +short GHS3DPlugin_Hypothesis::GetVerboseLevel() const +{ + return myVerboseLevel; +} + +//======================================================================= +//function : SetToCreateNewNodes +//======================================================================= + +void GHS3DPlugin_Hypothesis::SetToCreateNewNodes(bool toCreate) +{ + if ( myToCreateNewNodes != toCreate ) { + myToCreateNewNodes = toCreate; + NotifySubMeshesHypothesisModification(); + } +} + +//======================================================================= +//function : GetToCreateNewNodes +//======================================================================= + +bool GHS3DPlugin_Hypothesis::GetToCreateNewNodes() const +{ + return myToCreateNewNodes; +} + +//======================================================================= +//function : SetToUseBoundaryRecoveryVersion +//======================================================================= + +void GHS3DPlugin_Hypothesis::SetToUseBoundaryRecoveryVersion(bool toUse) +{ + if ( myToUseBoundaryRecoveryVersion != toUse ) { + myToUseBoundaryRecoveryVersion = toUse; + NotifySubMeshesHypothesisModification(); + } +} + +//======================================================================= +//function : GetToUseBoundaryRecoveryVersion +//======================================================================= + +bool GHS3DPlugin_Hypothesis::GetToUseBoundaryRecoveryVersion() const +{ + return myToUseBoundaryRecoveryVersion; +} + +//======================================================================= +//function : SetFEMCorrection +//======================================================================= + +void GHS3DPlugin_Hypothesis::SetFEMCorrection(bool toUseFem) +{ + if ( myToUseFemCorrection != toUseFem ) { + myToUseFemCorrection = toUseFem; + NotifySubMeshesHypothesisModification(); + } +} + +//======================================================================= +//function : GetFEMCorrection +//======================================================================= + +bool GHS3DPlugin_Hypothesis::GetFEMCorrection() const +{ + return myToUseFemCorrection; +} + +//======================================================================= +//function : SetToRemoveCentralPoint +//======================================================================= + +void GHS3DPlugin_Hypothesis::SetToRemoveCentralPoint(bool toRemove) +{ + if ( myToRemoveCentralPoint != toRemove ) { + myToRemoveCentralPoint = toRemove; + NotifySubMeshesHypothesisModification(); + } +} + +//======================================================================= +//function : GetToRemoveCentralPoint +//======================================================================= + +bool GHS3DPlugin_Hypothesis::GetToRemoveCentralPoint() const +{ + return myToRemoveCentralPoint; +} + +//======================================================================= +//function : SetTextOption +//======================================================================= + +void GHS3DPlugin_Hypothesis::SetTextOption(const std::string& option) +{ + if ( myTextOption != option ) { + myTextOption = option; + NotifySubMeshesHypothesisModification(); + } +} + +//======================================================================= +//function : GetTextOption +//======================================================================= + +std::string GHS3DPlugin_Hypothesis::GetTextOption() const +{ + return myTextOption; +} + +//======================================================================= +//function : SetEnforcedVertex +//======================================================================= + +void GHS3DPlugin_Hypothesis::SetEnforcedVertex(double x, double y, double z, double size) +{ + std::vector coord(3); + coord[0] = x; + coord[1] = y; + coord[2] = z; + myEnforcedVertices[coord] = size; + NotifySubMeshesHypothesisModification(); +} + +//======================================================================= +//function : GetEnforcedVertex +//======================================================================= + +double GHS3DPlugin_Hypothesis::GetEnforcedVertex(double x, double y, double z) + throw (std::invalid_argument) +{ + std::vector coord(3); + coord[0] = x; + coord[1] = y; + coord[2] = z; + if (myEnforcedVertices.count(coord)>0) + return myEnforcedVertices[coord]; + std::ostringstream msg ; + msg << "No enforced vertex at " << x << ", " << y << ", " << z; + throw std::invalid_argument(msg.str()); +} + +//======================================================================= +//function : RemoveEnforcedVertex +//======================================================================= + +void GHS3DPlugin_Hypothesis::RemoveEnforcedVertex(double x, double y, double z) + throw (std::invalid_argument) +{ + std::vector coord(3); + coord[0] = x; + coord[1] = y; + coord[2] = z; + TEnforcedVertexValues::iterator it = myEnforcedVertices.find(coord); + if (it != myEnforcedVertices.end()) { + myEnforcedVertices.erase(it); + NotifySubMeshesHypothesisModification(); + return; + } + std::ostringstream msg ; + msg << "No enforced vertex at " << x << ", " << y << ", " << z; + throw std::invalid_argument(msg.str()); +} + +//======================================================================= +//function : ClearEnforcedVertices +//======================================================================= +void GHS3DPlugin_Hypothesis::ClearEnforcedVertices() +{ + myEnforcedVertices.clear(); + NotifySubMeshesHypothesisModification(); +} + +//======================================================================= +//function : DefaultMeshHoles +//======================================================================= + +bool GHS3DPlugin_Hypothesis::DefaultMeshHoles() +{ + return false; // PAL19680 +} + +//======================================================================= +//function : DefaultMaximumMemory +//======================================================================= + +#ifndef WIN32 +#include +#else +#include +#endif + +short GHS3DPlugin_Hypothesis::DefaultMaximumMemory() +{ +#ifndef WIN32 + struct sysinfo si; + int err = sysinfo( &si ); + if ( err == 0 ) { + int ramMB = si.totalram * si.mem_unit / 1024 / 1024; + return (int) ( 0.7 * ramMB ); + } +#else + // See http://msdn.microsoft.com/en-us/library/aa366589.aspx + MEMORYSTATUSEX statex; + statex.dwLength = sizeof (statex); + int err = GlobalMemoryStatusEx (&statex); + if (err != 0) { + int totMB = + statex.ullTotalPhys / 1024 / 1024 + + statex.ullTotalPageFile / 1024 / 1024 + + statex.ullTotalVirtual / 1024 / 1024; + return (int) ( 0.7 * totMB ); + } +#endif + return 1024; +} + +//======================================================================= +//function : DefaultInitialMemory +//======================================================================= + +short GHS3DPlugin_Hypothesis::DefaultInitialMemory() +{ + return DefaultMaximumMemory(); +} + +//======================================================================= +//function : DefaultOptimizationLevel +//======================================================================= + +short GHS3DPlugin_Hypothesis::DefaultOptimizationLevel() +{ + return Medium; +} + +//======================================================================= +//function : DefaultWorkingDirectory +//======================================================================= + +std::string GHS3DPlugin_Hypothesis::DefaultWorkingDirectory() +{ + TCollection_AsciiString aTmpDir; + + char *Tmp_dir = getenv("SALOME_TMP_DIR"); + if(Tmp_dir != NULL) { + aTmpDir = Tmp_dir; + } + else { +#ifdef WIN32 + aTmpDir = TCollection_AsciiString("C:\\"); +#else + aTmpDir = TCollection_AsciiString("/tmp/"); +#endif + } + return aTmpDir.ToCString(); +} + +//======================================================================= +//function : DefaultKeepFiles +//======================================================================= + +bool GHS3DPlugin_Hypothesis::DefaultKeepFiles() +{ + return false; +} + +//======================================================================= +//function : DefaultVerboseLevel +//======================================================================= + +short GHS3DPlugin_Hypothesis::DefaultVerboseLevel() +{ + return 10; +} + +//======================================================================= +//function : DefaultToCreateNewNodes +//======================================================================= + +bool GHS3DPlugin_Hypothesis::DefaultToCreateNewNodes() +{ + return true; +} + +//======================================================================= +//function : DefaultToUseBoundaryRecoveryVersion +//======================================================================= + +bool GHS3DPlugin_Hypothesis::DefaultToUseBoundaryRecoveryVersion() +{ + return false; +} + +//======================================================================= +//function : DefaultToUseFEMCorrection +//======================================================================= + +bool GHS3DPlugin_Hypothesis::DefaultToUseFEMCorrection() +{ + return false; +} + +//======================================================================= +//function : DefaultToRemoveCentralPoint +//======================================================================= + +bool GHS3DPlugin_Hypothesis::DefaultToRemoveCentralPoint() +{ + return false; +} + +//======================================================================= +//function : DefaultEnforcedVertices +//======================================================================= + +GHS3DPlugin_Hypothesis::TEnforcedVertexValues GHS3DPlugin_Hypothesis::DefaultEnforcedVertices() +{ + return GHS3DPlugin_Hypothesis::TEnforcedVertexValues(); +} + + +//======================================================================= +//function : SaveTo +//======================================================================= + +std::ostream & GHS3DPlugin_Hypothesis::SaveTo(std::ostream & save) +{ + save << (int) myToMeshHoles << " "; + save << myMaximumMemory << " "; + save << myInitialMemory << " "; + save << myOptimizationLevel << " "; + save << myWorkingDirectory << " "; + save << (int)myKeepFiles << " "; + save << myVerboseLevel << " "; + save << (int)myToCreateNewNodes << " "; + save << (int)myToUseBoundaryRecoveryVersion << " "; + save << (int)myToUseFemCorrection << " "; + save << (int)myToRemoveCentralPoint << " "; + if (!myTextOption.empty()) { + save << "__OPTIONS_BEGIN__ "; + save << myTextOption << " "; + save << "__OPTIONS_END__ "; + } + + + TEnforcedVertexValues::iterator it = myEnforcedVertices.begin(); + if (it != myEnforcedVertices.end()) { + save << "__ENFORCED_VERTICES_BEGIN__ "; + for ( ; it != myEnforcedVertices.end(); ++it ) { + save << it->first[0] << " " + << it->first[1] << " " + << it->first[2] << " " + << it->second << " "; + } + save << "__ENFORCED_VERTICES_END__ "; + } + + return save; +} + +//======================================================================= +//function : LoadFrom +//======================================================================= + +std::istream & GHS3DPlugin_Hypothesis::LoadFrom(std::istream & load) +{ + bool isOK = true; + int i; + + isOK = (load >> i); + if (isOK) + myToMeshHoles = i; + else + load.clear(ios::badbit | load.rdstate()); + + isOK = (load >> i); + if (isOK) + myMaximumMemory = i; + else + load.clear(ios::badbit | load.rdstate()); + + isOK = (load >> i); + if (isOK) + myInitialMemory = i; + else + load.clear(ios::badbit | load.rdstate()); + + isOK = (load >> i); + if (isOK) + myOptimizationLevel = i; + else + load.clear(ios::badbit | load.rdstate()); + + isOK = (load >> myWorkingDirectory); + if (isOK) { + if ( myWorkingDirectory == "0") { // myWorkingDirectory was empty + myKeepFiles = false; + myWorkingDirectory.clear(); + } + else if ( myWorkingDirectory == "1" ) { + myKeepFiles = true; + myWorkingDirectory.clear(); + } + } + else + load.clear(ios::badbit | load.rdstate()); + + if ( !myWorkingDirectory.empty() ) { + isOK = (load >> i); + if (isOK) + myKeepFiles = i; + else + load.clear(ios::badbit | load.rdstate()); + } + + isOK = (load >> i); + if (isOK) + myVerboseLevel = (short) i; + else + load.clear(ios::badbit | load.rdstate()); + + isOK = (load >> i); + if (isOK) + myToCreateNewNodes = (bool) i; + else + load.clear(ios::badbit | load.rdstate()); + + isOK = (load >> i); + if (isOK) + myToUseBoundaryRecoveryVersion = (bool) i; + else + load.clear(ios::badbit | load.rdstate()); + + isOK = (load >> i); + if (isOK) + myToUseFemCorrection = (bool) i; + else + load.clear(ios::badbit | load.rdstate()); + + isOK = (load >> i); + if (isOK) + myToRemoveCentralPoint = (bool) i; + else + load.clear(ios::badbit | load.rdstate()); + + std::string separator; + bool hasOptions = false; + bool hasEnforcedVertices = false; + isOK = (load >> separator); + + if (isOK) { + if (separator == "__OPTIONS_BEGIN__") + hasOptions = true; + else if (separator == "__ENFORCED_VERTICES_BEGIN__") + hasEnforcedVertices = true; + } + + if (hasOptions) { + std::string txt; + while (isOK) { + isOK = (load >> txt); + if (isOK) { + if (txt == "__OPTIONS_END__") { + if (!myTextOption.empty()) { + // Remove last space + myTextOption.erase(myTextOption.end()-1); + } + isOK = false; + break; + } + myTextOption += txt; + myTextOption += " "; + } + } + } + + if (hasOptions) { + isOK = (load >> separator); + if (isOK) + if (separator == "__ENFORCED_VERTICES_BEGIN__") + hasEnforcedVertices = true; + } + + if (hasEnforcedVertices) { + std::string txt; + double x,y,z,size; + while (isOK) { + isOK = (load >> txt); + if (isOK) { + if (txt == "__ENFORCED_VERTICES_END__") { + isOK = false; + break; + } + x = atof(txt.c_str()); + isOK = (load >> y >> z >> size); + } + if (isOK) { + std::vector coord; + coord.push_back(x); + coord.push_back(y); + coord.push_back(z); + myEnforcedVertices[ coord ] = size; + } + } + } + + return load; +} + +//======================================================================= +//function : SetParametersByMesh +//======================================================================= + +bool GHS3DPlugin_Hypothesis::SetParametersByMesh(const SMESH_Mesh* ,const TopoDS_Shape&) +{ + return false; +} + + +//================================================================================ +/*! + * \brief Return false + */ +//================================================================================ + +bool GHS3DPlugin_Hypothesis::SetParametersByDefaults(const TDefaults& /*dflts*/, + const SMESH_Mesh* /*theMesh*/) +{ + return false; +} + +//================================================================================ +/*! + * \brief Return command to run ghs3d mesher excluding file prefix (-f) + */ +//================================================================================ + +std::string GHS3DPlugin_Hypothesis::CommandToRun(const GHS3DPlugin_Hypothesis* hyp, + const bool hasShapeToMesh) +{ + TCollection_AsciiString cmd( "ghs3d" ); + // check if any option is overridden by hyp->myTextOption + bool m = hyp ? ( hyp->myTextOption.find("-m") == std::string::npos ) : true; + bool M = hyp ? ( hyp->myTextOption.find("-M") == std::string::npos ) : true; + bool c = hyp ? ( hyp->myTextOption.find("-c") == std::string::npos ) : true; + bool o = hyp ? ( hyp->myTextOption.find("-o") == std::string::npos ) : true; + bool p0 = hyp ? ( hyp->myTextOption.find("-p0") == std::string::npos ) : true; + bool C = hyp ? ( hyp->myTextOption.find("-C") == std::string::npos ) : true; + bool v = hyp ? ( hyp->myTextOption.find("-v") == std::string::npos ) : true; + bool fem = hyp ? ( hyp->myTextOption.find("-FEM")== std::string::npos ) : true; + bool rem = hyp ? ( hyp->myTextOption.find("-no_initial_central_point")== std::string::npos ) : true; + + // if use boundary recovery version, few options are allowed + bool useBndRecovery = !C; + if ( !useBndRecovery && hyp ) + useBndRecovery = hyp->myToUseBoundaryRecoveryVersion; + + // ghs3d needs 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 + if ( m ) { + short aMaximumMemory = hyp ? hyp->myMaximumMemory : -1; + cmd += " -m "; + if ( aMaximumMemory < 0 ) + cmd += DefaultMaximumMemory(); + else + cmd += aMaximumMemory; + } + if ( M && !useBndRecovery ) { + short aInitialMemory = hyp ? hyp->myInitialMemory : -1; + cmd += " -M "; + if ( aInitialMemory > 0 ) + cmd += aInitialMemory; + else + cmd += "100"; + } + // component to mesh + // 0 , all components to be meshed + // 1 , only the main ( outermost ) component to be meshed + if ( c && !useBndRecovery ) { + // We always run GHS3D with "to mesh holes'==TRUE (see PAL19680) + if ( hasShapeToMesh ) + cmd += " -c 0"; + else { + bool aToMeshHoles = hyp ? hyp->myToMeshHoles : DefaultMeshHoles(); + if ( aToMeshHoles ) + cmd += " -c 0"; + else + cmd += " -c 1"; + } + } + + // optimization level + if ( o && hyp && !useBndRecovery ) { + if ( hyp->myOptimizationLevel >= 0 && hyp->myOptimizationLevel < 5 ) { + const char* level[] = { "none" , "light" , "standard" , "standard+" , "strong" }; + cmd += " -o "; + cmd += level[ hyp->myOptimizationLevel ]; + } + } + + // to create internal nodes + if ( p0 && hyp && !hyp->myToCreateNewNodes ) { + cmd += " -p0"; + } + + // verbose mode + if ( v && hyp ) { + cmd += " -v "; + cmd += hyp->myVerboseLevel; + } + + // boundary recovery version + if ( useBndRecovery ) { + cmd += " -C"; + } + + // to use FEM correction + if ( fem && hyp && hyp->myToUseFemCorrection) { + cmd += " -FEM"; + } + + // to remove initial central point. + if ( rem && hyp && hyp->myToRemoveCentralPoint) { + cmd += " -no_initial_central_point"; + } + + // options as text + if ( hyp && !hyp->myTextOption.empty() ) { + cmd += " "; + cmd += (char*) hyp->myTextOption.c_str(); + } + +#ifdef WNT + cmd += " < NUL"; +#endif + + return cmd.ToCString(); +} + +//================================================================================ +/*! + * \brief Return a unique file name + */ +//================================================================================ + +std::string GHS3DPlugin_Hypothesis::GetFileName(const GHS3DPlugin_Hypothesis* hyp) +{ + std::string aTmpDir = hyp ? hyp->GetWorkingDirectory() : DefaultWorkingDirectory(); + const char lastChar = *aTmpDir.rbegin(); +#ifdef WIN32 + if(lastChar != '\\') aTmpDir+='\\'; +#else + if(lastChar != '/') aTmpDir+='/'; +#endif + + TCollection_AsciiString aGenericName = (char*)aTmpDir.c_str(); + aGenericName += "GHS3D_"; + aGenericName += getpid(); + aGenericName += "_"; + aGenericName += Abs((Standard_Integer)(long) aGenericName.ToCString()); + + return aGenericName.ToCString(); +} + + +//================================================================================ +/*! +* \brief Return the enforced vertices +*/ +//================================================================================ + +GHS3DPlugin_Hypothesis::TEnforcedVertexValues GHS3DPlugin_Hypothesis::GetEnforcedVertices(const GHS3DPlugin_Hypothesis* hyp) +{ + return hyp ? hyp->_GetEnforcedVertices():DefaultEnforcedVertices(); +} + diff --git a/src/GHS3DPlugin/GHS3DPlugin_Hypothesis.hxx b/src/GHS3DPlugin/GHS3DPlugin_Hypothesis.hxx new file mode 100644 index 0000000..28fe2bb --- /dev/null +++ b/src/GHS3DPlugin/GHS3DPlugin_Hypothesis.hxx @@ -0,0 +1,189 @@ +// Copyright (C) 2004-2010 CEA/DEN, EDF R&D +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +// GHS3DPlugin : C++ implementation +// File : GHS3DPlugin_Hypothesis.hxx +// Created : Wed Apr 2 12:21:17 2008 +// Author : Edward AGAPOV (eap) +// +#ifndef GHS3DPlugin_Hypothesis_HeaderFile +#define GHS3DPlugin_Hypothesis_HeaderFile + +#include "GHS3DPlugin_Defs.hxx" + +#include +#include + +#include +#include +#include +#include + +class GHS3DPLUGIN_EXPORT GHS3DPlugin_Hypothesis: public SMESH_Hypothesis +{ +public: + + GHS3DPlugin_Hypothesis(int hypId, int studyId, SMESH_Gen * gen); + + /*! + * To mesh "holes" in a solid or not. Default is to mesh. + */ + void SetToMeshHoles(bool toMesh); + bool GetToMeshHoles(bool checkFreeOption = false) const; + /*! + * Maximal size of memory to be used by the algorithm (in Megabytes) + */ + void SetMaximumMemory(short MB); + short GetMaximumMemory() const; + /*! + * Initial size of memory to be used by the algorithm (in Megabytes) in + * automatic memory adjustment mode. Default is zero + */ + void SetInitialMemory(short MB); + short GetInitialMemory() const; + /*! + * Optimization level: 0-none, 1-light, 2-medium, 3-standard+, 4-strong. Default is medium + */ + enum OptimizationLevel { None = 0, Light, Medium, StandardPlus, Strong }; + void SetOptimizationLevel(OptimizationLevel level); + OptimizationLevel GetOptimizationLevel() const; + /*! + * Path to working directory + */ + void SetWorkingDirectory(const std::string& path); + std::string GetWorkingDirectory() const; + /*! + * To keep working files or remove them. Log file remains in case of errors anyway. + */ + void SetKeepFiles(bool toKeep); + bool GetKeepFiles() const; + /*! + * Verbose level [0-10] + * 0 - no standard output, + * 2 - prints the data, quality statistics of the skin and final meshes and + * indicates when the final mesh is being saved. In addition the software + * gives indication regarding the CPU time. + * 10 - same as 2 plus the main steps in the computation, quality statistics + * histogram of the skin mesh, quality statistics histogram together with + * the characteristics of the final mesh. + */ + void SetVerboseLevel(short level); + short GetVerboseLevel() const; + /*! + * To create new nodes + */ + void SetToCreateNewNodes(bool toCreate); + bool GetToCreateNewNodes() const; + /*! + * To use boundary recovery version which tries to create mesh on a very poor + * quality surface mesh + */ + void SetToUseBoundaryRecoveryVersion(bool toUse); + bool GetToUseBoundaryRecoveryVersion() const; + /*! + * Applies finite-element correction by replacing overconstrained elements where + * it is possible. The process is cutting first the overconstrained edges and + * second the overconstrained facets. This insure that no edges have two boundary + * vertices and that no facets have three boundary vertices. + */ + void SetFEMCorrection(bool toUseFem); + bool GetFEMCorrection() const; + /*! + * To removes initial central point. + */ + void SetToRemoveCentralPoint(bool toRemove); + bool GetToRemoveCentralPoint() const; + /*! + * To set hiden/undocumented/advanced options + */ + void SetTextOption(const std::string& option); + std::string GetTextOption() const; + /*! + * To set an enforced vertex + */ + typedef std::map,double> TEnforcedVertexValues; + void SetEnforcedVertex(double x, double y, double z, double size); + double GetEnforcedVertex(double x, double y, double z) throw (std::invalid_argument); + void RemoveEnforcedVertex(double x, double y, double z) throw (std::invalid_argument); + const TEnforcedVertexValues _GetEnforcedVertices() const { return myEnforcedVertices; } + void ClearEnforcedVertices(); + + static bool DefaultMeshHoles(); + static short DefaultMaximumMemory(); + static short DefaultInitialMemory(); + static short DefaultOptimizationLevel(); + static std::string DefaultWorkingDirectory(); + static bool DefaultKeepFiles(); + static short DefaultVerboseLevel(); + static bool DefaultToCreateNewNodes(); + static bool DefaultToUseBoundaryRecoveryVersion(); + static bool DefaultToUseFEMCorrection(); + static bool DefaultToRemoveCentralPoint(); + static TEnforcedVertexValues DefaultEnforcedVertices(); + + /*! + * \brief Return command to run ghs3d mesher excluding file prefix (-f) + */ + static std::string CommandToRun(const GHS3DPlugin_Hypothesis* hyp, + const bool hasShapeToMesh=true); + /*! + * \brief Return a unique file name + */ + static std::string GetFileName(const GHS3DPlugin_Hypothesis* hyp); + /*! + * \brief Return the enforced vertices + */ + static TEnforcedVertexValues GetEnforcedVertices(const GHS3DPlugin_Hypothesis* hyp); + + // Persistence + virtual std::ostream & SaveTo(std::ostream & save); + virtual std::istream & LoadFrom(std::istream & load); + friend GHS3DPLUGIN_EXPORT std::ostream & operator <<(std::ostream & save, GHS3DPlugin_Hypothesis & hyp); + friend GHS3DPLUGIN_EXPORT std::istream & operator >>(std::istream & load, GHS3DPlugin_Hypothesis & hyp); + + /*! + * \brief Does nothing + */ + virtual bool SetParametersByMesh(const SMESH_Mesh* theMesh, const TopoDS_Shape& theShape); + + /*! + * \brief Does nothing + */ + virtual bool SetParametersByDefaults(const TDefaults& dflts, const SMESH_Mesh* theMesh=0); + +private: + + bool myToMeshHoles; + short myMaximumMemory; + short myInitialMemory; + short myOptimizationLevel; + bool myKeepFiles; + std::string myWorkingDirectory; + short myVerboseLevel; + bool myToCreateNewNodes; + bool myToUseBoundaryRecoveryVersion; + bool myToUseFemCorrection; + bool myToRemoveCentralPoint; + std::string myTextOption; + TEnforcedVertexValues myEnforcedVertices; + +}; + + +#endif diff --git a/src/GHS3DPlugin/GHS3DPlugin_Hypothesis_i.cxx b/src/GHS3DPlugin/GHS3DPlugin_Hypothesis_i.cxx new file mode 100644 index 0000000..ff3953e --- /dev/null +++ b/src/GHS3DPlugin/GHS3DPlugin_Hypothesis_i.cxx @@ -0,0 +1,460 @@ +// Copyright (C) 2004-2010 CEA/DEN, EDF R&D +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +// File : GHS3DPlugin_Hypothesis_i.cxx +// Created : Wed Apr 2 13:53:01 2008 +// Author : Edward AGAPOV (eap) +// +#include "GHS3DPlugin_Hypothesis_i.hxx" + +#include +#include + +#include +#include +#include + +//======================================================================= +//function : GHS3DPlugin_Hypothesis_i +//======================================================================= + +GHS3DPlugin_Hypothesis_i::GHS3DPlugin_Hypothesis_i (PortableServer::POA_ptr thePOA, + int theStudyId, + ::SMESH_Gen* theGenImpl) + : SALOME::GenericObj_i( thePOA ), + SMESH_Hypothesis_i( thePOA ) +{ + MESSAGE( "GHS3DPlugin_Hypothesis_i::GHS3DPlugin_Hypothesis_i" ); + myBaseImpl = new ::GHS3DPlugin_Hypothesis (theGenImpl->GetANewId(), + theStudyId, + theGenImpl); +} + +//======================================================================= +//function : ~GHS3DPlugin_Hypothesis_i +//======================================================================= + +GHS3DPlugin_Hypothesis_i::~GHS3DPlugin_Hypothesis_i() +{ + MESSAGE( "GHS3DPlugin_Hypothesis_i::~GHS3DPlugin_Hypothesis_i" ); +} + +//======================================================================= +//function : SetToMeshHoles +//======================================================================= + +void GHS3DPlugin_Hypothesis_i::SetToMeshHoles(CORBA::Boolean toMesh) +{ + ASSERT(myBaseImpl); + this->GetImpl()->SetToMeshHoles(toMesh); + SMESH::TPythonDump() << _this() << ".SetToMeshHoles( " << toMesh << " )"; +} + +//======================================================================= +//function : GetToMeshHoles +//======================================================================= + +CORBA::Boolean GHS3DPlugin_Hypothesis_i::GetToMeshHoles() +{ + ASSERT(myBaseImpl); + return this->GetImpl()->GetToMeshHoles(); +} + +//======================================================================= +//function : SetMaximumMemory +//======================================================================= + +void GHS3DPlugin_Hypothesis_i::SetMaximumMemory(CORBA::Short MB) + throw ( SALOME::SALOME_Exception ) +{ + if ( MB == 0 ) + THROW_SALOME_CORBA_EXCEPTION( "Invalid memory size",SALOME::BAD_PARAM ); + ASSERT(myBaseImpl); + this->GetImpl()->SetMaximumMemory(MB); + SMESH::TPythonDump() << _this() << ".SetMaximumMemory( " << MB << " )"; +} + +//======================================================================= +//function : GetMaximumMemory +//======================================================================= + +CORBA::Short GHS3DPlugin_Hypothesis_i::GetMaximumMemory() +{ + ASSERT(myBaseImpl); + return this->GetImpl()->GetMaximumMemory(); +} + +//======================================================================= +//function : SetInitialMemory +//======================================================================= + +void GHS3DPlugin_Hypothesis_i::SetInitialMemory(CORBA::Short MB) + throw ( SALOME::SALOME_Exception ) +{ + if ( MB == 0 ) + THROW_SALOME_CORBA_EXCEPTION( "Invalid memory size",SALOME::BAD_PARAM ); + ASSERT(myBaseImpl); + this->GetImpl()->SetInitialMemory(MB); + SMESH::TPythonDump() << _this() << ".SetInitialMemory( " << MB << " )"; +} + +//======================================================================= +//function : GetInitialMemory +//======================================================================= + +CORBA::Short GHS3DPlugin_Hypothesis_i::GetInitialMemory() +{ + ASSERT(myBaseImpl); + return this->GetImpl()->GetInitialMemory(); +} + +//======================================================================= +//function : SetOptimizationLevel +//======================================================================= + +void GHS3DPlugin_Hypothesis_i::SetOptimizationLevel(CORBA::Short level) + throw ( SALOME::SALOME_Exception ) +{ + ::GHS3DPlugin_Hypothesis::OptimizationLevel l = + (::GHS3DPlugin_Hypothesis::OptimizationLevel) level; + if ( l < ::GHS3DPlugin_Hypothesis::None || + l > ::GHS3DPlugin_Hypothesis::Strong ) + THROW_SALOME_CORBA_EXCEPTION( "Invalid optimization level",SALOME::BAD_PARAM ); + + ASSERT(myBaseImpl); + this->GetImpl()->SetOptimizationLevel(l); + SMESH::TPythonDump() << _this() << ".SetOptimizationLevel( " << level << " )"; +} + +//======================================================================= +//function : GetOptimizationLevel +//======================================================================= + +CORBA::Short GHS3DPlugin_Hypothesis_i::GetOptimizationLevel() +{ + ASSERT(myBaseImpl); + return this->GetImpl()->GetOptimizationLevel(); +} + +//======================================================================= +//function : SetWorkingDirectory +//======================================================================= + +void GHS3DPlugin_Hypothesis_i::SetWorkingDirectory(const char* path) throw ( SALOME::SALOME_Exception ) +{ + if (!path ) + THROW_SALOME_CORBA_EXCEPTION( "Null working directory",SALOME::BAD_PARAM ); + + string file(path); + const char lastChar = *file.rbegin(); +#ifdef WIN32 + if ( lastChar != '\\' ) file += '\\'; +#else + if ( lastChar != '/' ) file += '/'; +#endif + file += "GHS3D.log"; + SMESH_Mesh_i::PrepareForWriting (file.c_str()); + + ASSERT(myBaseImpl); + this->GetImpl()->SetWorkingDirectory(path); + SMESH::TPythonDump() << _this() << ".SetWorkingDirectory( '" << path << "' )"; +} + +//======================================================================= +//function : GetWorkingDirectory +//======================================================================= + +char* GHS3DPlugin_Hypothesis_i::GetWorkingDirectory() +{ + ASSERT(myBaseImpl); + return CORBA::string_dup( this->GetImpl()->GetWorkingDirectory().c_str() ); +} + +//======================================================================= +//function : SetKeepFiles +//======================================================================= + +void GHS3DPlugin_Hypothesis_i::SetKeepFiles(CORBA::Boolean toKeep) +{ + ASSERT(myBaseImpl); + this->GetImpl()->SetKeepFiles(toKeep); + SMESH::TPythonDump() << _this() << ".SetKeepFiles( " << toKeep << " )"; +} + +//======================================================================= +//function : GetKeepFiles +//======================================================================= + +CORBA::Boolean GHS3DPlugin_Hypothesis_i::GetKeepFiles() +{ + ASSERT(myBaseImpl); + return this->GetImpl()->GetKeepFiles(); +} + +//======================================================================= +//function : SetVerboseLevel +//======================================================================= + +void GHS3DPlugin_Hypothesis_i::SetVerboseLevel(CORBA::Short level) + throw ( SALOME::SALOME_Exception ) +{ + if (level < 0 || level > 10 ) + THROW_SALOME_CORBA_EXCEPTION( "Invalid verbose level, valid range is [0-10]", + SALOME::BAD_PARAM ); + ASSERT(myBaseImpl); + this->GetImpl()->SetVerboseLevel(level); + SMESH::TPythonDump() << _this() << ".SetVerboseLevel( " << level << " )"; +} + +//======================================================================= +//function : GetVerboseLevel +//======================================================================= + +CORBA::Short GHS3DPlugin_Hypothesis_i::GetVerboseLevel() +{ + ASSERT(myBaseImpl); + return this->GetImpl()->GetVerboseLevel(); +} + +//======================================================================= +//function : SetToCreateNewNodes +//======================================================================= + +void GHS3DPlugin_Hypothesis_i::SetToCreateNewNodes(CORBA::Boolean toCreate) +{ + ASSERT(myBaseImpl); + this->GetImpl()->SetToCreateNewNodes(toCreate); + SMESH::TPythonDump() << _this() << ".SetToCreateNewNodes( " << toCreate << " )"; +} + +//======================================================================= +//function : GetToCreateNewNodes +//======================================================================= + +CORBA::Boolean GHS3DPlugin_Hypothesis_i::GetToCreateNewNodes() +{ + ASSERT(myBaseImpl); + return this->GetImpl()->GetToCreateNewNodes(); +} + +//======================================================================= +//function : SetToUseBoundaryRecoveryVersion +//======================================================================= + +void GHS3DPlugin_Hypothesis_i::SetToUseBoundaryRecoveryVersion(CORBA::Boolean toUse) +{ + ASSERT(myBaseImpl); + this->GetImpl()->SetToUseBoundaryRecoveryVersion(toUse); + SMESH::TPythonDump() << _this() << ".SetToUseBoundaryRecoveryVersion( " << toUse << " )"; +} + +//======================================================================= +//function : GetToUseBoundaryRecoveryVersion +//======================================================================= + +CORBA::Boolean GHS3DPlugin_Hypothesis_i::GetToUseBoundaryRecoveryVersion() +{ + ASSERT(myBaseImpl); + return this->GetImpl()->GetToUseBoundaryRecoveryVersion(); +} + +//======================================================================= +//function : SetFEMCorrection +//======================================================================= + +void GHS3DPlugin_Hypothesis_i::SetFEMCorrection(CORBA::Boolean toUseFem) +{ + ASSERT(myBaseImpl); + this->GetImpl()->SetFEMCorrection(toUseFem); + SMESH::TPythonDump() << _this() << ".SetFEMCorrection( " << toUseFem << " )"; +} + +//======================================================================= +//function : GetFEMCorrection +//======================================================================= + +CORBA::Boolean GHS3DPlugin_Hypothesis_i::GetFEMCorrection() +{ + ASSERT(myBaseImpl); + return this->GetImpl()->GetFEMCorrection(); +} + +//======================================================================= +//function : SetToRemoveCentralPoint +//======================================================================= + +void GHS3DPlugin_Hypothesis_i::SetToRemoveCentralPoint(CORBA::Boolean toRemove) +{ + ASSERT(myBaseImpl); + this->GetImpl()->SetToRemoveCentralPoint(toRemove); + SMESH::TPythonDump() << _this() << ".SetToRemoveCentralPoint( " << toRemove << " )"; +} + +//======================================================================= +//function : GetToRemoveCentralPoint +//======================================================================= + +CORBA::Boolean GHS3DPlugin_Hypothesis_i::GetToRemoveCentralPoint() +{ + ASSERT(myBaseImpl); + return this->GetImpl()->GetToRemoveCentralPoint(); +} + +//======================================================================= +//function : SetTextOption +//======================================================================= + +void GHS3DPlugin_Hypothesis_i::SetTextOption(const char* option) +{ + ASSERT(myBaseImpl); + this->GetImpl()->SetTextOption(option); + SMESH::TPythonDump() << _this() << ".SetTextOption( '" << option << "' )"; +} + +//======================================================================= +//function : GetTextOption +//======================================================================= + +char* GHS3DPlugin_Hypothesis_i::GetTextOption() +{ + ASSERT(myBaseImpl); + return CORBA::string_dup( this->GetImpl()->GetTextOption().c_str() ); +} + +//======================================================================= +//function : SetEnforcedVertex +//======================================================================= + +void GHS3DPlugin_Hypothesis_i::SetEnforcedVertex(CORBA::Double x, CORBA::Double y, CORBA::Double z, CORBA::Double size) +{ + ASSERT(myBaseImpl); + this->GetImpl()->SetEnforcedVertex(x,y,z,size); + SMESH::TPythonDump() << _this() << ".SetEnforcedVertex( " << x << ", " << y << ", " << z << ", " << size << " )"; +} + +//======================================================================= +//function : GetEnforcedVertex +//======================================================================= + +CORBA::Double GHS3DPlugin_Hypothesis_i::GetEnforcedVertex(CORBA::Double x, CORBA::Double y, CORBA::Double z) + throw (SALOME::SALOME_Exception) +{ + ASSERT(myBaseImpl); + try { + return this->GetImpl()->GetEnforcedVertex(x,y,z); + } + catch (const std::invalid_argument& ex) { + SALOME::ExceptionStruct ExDescription; + ExDescription.text = ex.what(); + ExDescription.type = SALOME::BAD_PARAM; + ExDescription.sourceFile = "GHS3DPlugin_Hypothesis::GetEnforcedVertex(x,y,z)"; + ExDescription.lineNumber = 0; + throw SALOME::SALOME_Exception(ExDescription); + } + catch (SALOME_Exception& ex) { + THROW_SALOME_CORBA_EXCEPTION( ex.what() ,SALOME::BAD_PARAM ); + } + return 0; +} + +//======================================================================= +//function : GetEnforcedVertices +//======================================================================= + +GHS3DPlugin::GHS3DEnforcedVertexList* GHS3DPlugin_Hypothesis_i::GetEnforcedVertices() +{ + ASSERT(myBaseImpl); + GHS3DPlugin::GHS3DEnforcedVertexList_var result = new GHS3DPlugin::GHS3DEnforcedVertexList(); + + const ::GHS3DPlugin_Hypothesis::TEnforcedVertexValues sizeMaps = this->GetImpl()->_GetEnforcedVertices(); + int size = sizeMaps.size(); + result->length( size ); + + ::GHS3DPlugin_Hypothesis::TEnforcedVertexValues::const_iterator it; + int i = 0; + for (it = sizeMaps.begin() ; it != sizeMaps.end(); it++ ) { + GHS3DPlugin::GHS3DEnforcedVertex_var myVertex = new GHS3DPlugin::GHS3DEnforcedVertex(); + myVertex->x = it->first[0]; + myVertex->y = it->first[1]; + myVertex->z = it->first[2]; + myVertex->size = it->second; + result[i]=myVertex; + i++; + } + + return result._retn(); +} + +//======================================================================= +//function : RemoveEnforcedVertex +//======================================================================= + +void GHS3DPlugin_Hypothesis_i::RemoveEnforcedVertex(CORBA::Double x, CORBA::Double y, CORBA::Double z) + throw (SALOME::SALOME_Exception) +{ + ASSERT(myBaseImpl); + try { + this->GetImpl()->RemoveEnforcedVertex(x,y,z); + SMESH::TPythonDump() << _this() << ".RemoveEnforcedVertex( " << x << ", " << y << ", " << z << " )"; + } + catch (const std::invalid_argument& ex) { + SALOME::ExceptionStruct ExDescription; + ExDescription.text = ex.what(); + ExDescription.type = SALOME::BAD_PARAM; + ExDescription.sourceFile = "GHS3DPlugin_Hypothesis::RemoveEnforcedVertex(x,y,z)"; + ExDescription.lineNumber = 0; + throw SALOME::SALOME_Exception(ExDescription); + } + catch (SALOME_Exception& ex) { + THROW_SALOME_CORBA_EXCEPTION( ex.what() ,SALOME::BAD_PARAM ); + } +} + +//======================================================================= +//function : ClearEnforcedVertices +//======================================================================= + +void GHS3DPlugin_Hypothesis_i::ClearEnforcedVertices() +{ + ASSERT(myBaseImpl); + this->GetImpl()->ClearEnforcedVertices(); +} + +//============================================================================= +/*! + * Get implementation + */ +//============================================================================= + +::GHS3DPlugin_Hypothesis* GHS3DPlugin_Hypothesis_i::GetImpl() +{ + return (::GHS3DPlugin_Hypothesis*)myBaseImpl; +} + +//================================================================================ +/*! + * \brief Verify whether hypothesis supports given entity type + */ +//================================================================================ + +CORBA::Boolean GHS3DPlugin_Hypothesis_i::IsDimSupported( SMESH::Dimension type ) +{ + return type == SMESH::DIM_3D; +} + diff --git a/src/GHS3DPlugin/GHS3DPlugin_Hypothesis_i.hxx b/src/GHS3DPlugin/GHS3DPlugin_Hypothesis_i.hxx new file mode 100644 index 0000000..0cf9a26 --- /dev/null +++ b/src/GHS3DPlugin/GHS3DPlugin_Hypothesis_i.hxx @@ -0,0 +1,140 @@ +// Copyright (C) 2004-2010 CEA/DEN, EDF R&D +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +// GHS3DPlugin : C++ implementation +// File : GHS3DPlugin_Hypothesis_i.hxx +// Date : 03/04/2006 +// Project : SALOME +// +#ifndef _GHS3DPlugin_Hypothesis_i_HXX_ +#define _GHS3DPlugin_Hypothesis_i_HXX_ + +#include "GHS3DPlugin_Defs.hxx" + +#include +#include CORBA_SERVER_HEADER(GHS3DPlugin_Algorithm) + +#include "SMESH_Hypothesis_i.hxx" +#include "GHS3DPlugin_Hypothesis.hxx" + +class SMESH_Gen; + +// GHS3DPlugin parameters hypothesis + +class GHS3DPLUGIN_EXPORT GHS3DPlugin_Hypothesis_i: + public virtual POA_GHS3DPlugin::GHS3DPlugin_Hypothesis, + public virtual SMESH_Hypothesis_i +{ + public: + // Constructor + GHS3DPlugin_Hypothesis_i (PortableServer::POA_ptr thePOA, + int theStudyId, + ::SMESH_Gen* theGenImpl); + // Destructor + virtual ~GHS3DPlugin_Hypothesis_i(); + + /*! + * To mesh "holes" in a solid or not. Default is to mesh. + */ + void SetToMeshHoles(CORBA::Boolean toMesh); + CORBA::Boolean GetToMeshHoles(); + /*! + * Maximal size of memory to be used by the algorithm (in Megabytes) + */ + void SetMaximumMemory(CORBA::Short MB) throw ( SALOME::SALOME_Exception ); + CORBA::Short GetMaximumMemory(); + /*! + * Initial size of memory to be used by the algorithm (in Megabytes) in + * automatic memory adjustment mode. Default is zero + */ + void SetInitialMemory(CORBA::Short MB) throw ( SALOME::SALOME_Exception ); + CORBA::Short GetInitialMemory(); + /*! + * Optimization level: 0-none, 1-light, 2-medium, 3-strong. Default is medium + */ + void SetOptimizationLevel(CORBA::Short level) throw ( SALOME::SALOME_Exception ); + CORBA::Short GetOptimizationLevel(); + /*! + * Path to working directory + */ + void SetWorkingDirectory(const char* path) throw ( SALOME::SALOME_Exception ); + char* GetWorkingDirectory(); + /*! + * To keep working files or remove them. Log file remains in case of errors anyway. + */ + void SetKeepFiles(CORBA::Boolean toKeep); + CORBA::Boolean GetKeepFiles(); + /*! + * Verbose level [0-10] + * 0 - no standard output, + * 2 - prints the data, quality statistics of the skin and final meshes and + * indicates when the final mesh is being saved. In addition the software + * gives indication regarding the CPU time. + * 10 - same as 2 plus the main steps in the computation, quality statistics + * histogram of the skin mesh, quality statistics histogram together with + * the characteristics of the final mesh. + */ + void SetVerboseLevel(CORBA::Short level) throw ( SALOME::SALOME_Exception ); + CORBA::Short GetVerboseLevel(); + /*! + * To create new nodes + */ + void SetToCreateNewNodes(CORBA::Boolean toCreate); + CORBA::Boolean GetToCreateNewNodes(); + /*! + * To use boundary recovery version which tries to create mesh on a very poor + * quality surface mesh + */ + void SetToUseBoundaryRecoveryVersion(CORBA::Boolean toUse); + CORBA::Boolean GetToUseBoundaryRecoveryVersion(); + /*! + * Applies finite-element correction by replacing overconstrained elements where + * it is possible. The process is cutting first the overconstrained edges and + * second the overconstrained facets. This insure that no edges have two boundary + * vertices and that no facets have three boundary vertices. + */ + void SetFEMCorrection(CORBA::Boolean toUseFem); + CORBA::Boolean GetFEMCorrection(); + /*! + * To removes initial central point. + */ + void SetToRemoveCentralPoint(CORBA::Boolean toRemove); + CORBA::Boolean GetToRemoveCentralPoint(); + /*! + * To set hiden/undocumented/advanced options + */ + void SetTextOption(const char* option); + char* GetTextOption(); + /*! + * To set an enforced vertex + */ + void SetEnforcedVertex(CORBA::Double x, CORBA::Double y, CORBA::Double z, CORBA::Double size); + CORBA::Double GetEnforcedVertex(CORBA::Double x, CORBA::Double y, CORBA::Double z) throw (SALOME::SALOME_Exception); + void RemoveEnforcedVertex(CORBA::Double x, CORBA::Double y, CORBA::Double z) throw (SALOME::SALOME_Exception); + GHS3DPlugin::GHS3DEnforcedVertexList* GetEnforcedVertices(); + void ClearEnforcedVertices(); + + // Get implementation + ::GHS3DPlugin_Hypothesis* GetImpl(); + + // Verify whether hypothesis supports given entity type + CORBA::Boolean IsDimSupported( SMESH::Dimension type ); +}; + +#endif diff --git a/src/GHS3DPlugin/GHS3DPlugin_i.cxx b/src/GHS3DPlugin/GHS3DPlugin_i.cxx new file mode 100644 index 0000000..f1dbdfb --- /dev/null +++ b/src/GHS3DPlugin/GHS3DPlugin_i.cxx @@ -0,0 +1,70 @@ +// Copyright (C) 2004-2010 CEA/DEN, EDF R&D +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +// SMESH GHS3DPlugin : implementaion of SMESH idl descriptions +// File : GHS3DPlugin.cxx +// Author : Julia DOROVSKIKH +// Module : SMESH +// $Header$ +// +#include "SMESH_Hypothesis_i.hxx" + +#include "utilities.h" + +#include "GHS3DPlugin_GHS3D_i.hxx" +#include "GHS3DPlugin_Hypothesis_i.hxx" + +using namespace std; + +template class GHS3DPlugin_Creator_i:public HypothesisCreator_i +{ + // as we have 'module GHS3DPlugin' in GHS3DPlugin_Algorithm.idl + virtual std::string GetModuleName() { return "GHS3DPlugin"; } +}; + +//============================================================================= +/*! + * + */ +//============================================================================= + +extern "C" +{ + GenericHypothesisCreator_i* GetHypothesisCreator (const char* aHypName); + + GHS3DPLUGIN_EXPORT + GenericHypothesisCreator_i* GetHypothesisCreator (const char* aHypName) + { + MESSAGE("GetHypothesisCreator " << aHypName); + + GenericHypothesisCreator_i* aCreator = 0; + + // Hypotheses + + // Algorithm + if (strcmp(aHypName, "GHS3D_3D") == 0) + aCreator = new GHS3DPlugin_Creator_i; + // Hypothesis + else if (strcmp(aHypName, "GHS3D_Parameters") == 0) + aCreator = new GHS3DPlugin_Creator_i; + else ; + + return aCreator; + } +} diff --git a/src/GHS3DPlugin/Makefile.am b/src/GHS3DPlugin/Makefile.am new file mode 100644 index 0000000..2875199 --- /dev/null +++ b/src/GHS3DPlugin/Makefile.am @@ -0,0 +1,63 @@ +# Copyright (C) 2004-2010 CEA/DEN, EDF R&D +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# +# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +# + +# -* Makefile *- +# Author : Edward AGAPOV (OCC) +# Modified by : Alexander BORODIN (OCN) - autotools usage +# Module : GHS3DPLUGIN +# Date : 10/01/2004 +# +include $(top_srcdir)/adm_local/unix/make_common_starter.am + +# header files +salomeinclude_HEADERS = \ + GHS3DPlugin_Defs.hxx \ + GHS3DPlugin_GHS3D.hxx \ + GHS3DPlugin_GHS3D_i.hxx \ + GHS3DPlugin_Hypothesis.hxx \ + GHS3DPlugin_Hypothesis_i.hxx + +# Libraries targets +lib_LTLIBRARIES = libGHS3DEngine.la + +dist_libGHS3DEngine_la_SOURCES = \ + GHS3DPlugin_GHS3D.cxx \ + GHS3DPlugin_GHS3D_i.cxx \ + GHS3DPlugin_i.cxx \ + GHS3DPlugin_Hypothesis.cxx \ + GHS3DPlugin_Hypothesis_i.cxx + +libGHS3DEngine_la_CPPFLAGS = \ + $(KERNEL_CXXFLAGS) \ + $(CAS_CPPFLAGS) \ + $(GEOM_CXXFLAGS) \ + $(MED_CXXFLAGS) \ + $(SMESH_CXXFLAGS) \ + $(VTK_INCLUDES) \ + $(BOOST_CPPFLAGS) \ + $(CORBA_CXXFLAGS) \ + $(CORBA_INCLUDES) \ + -I$(top_builddir)/idl + +libGHS3DEngine_la_LDFLAGS = \ + ../../idl/libSalomeIDLGHS3DPLUGIN.la \ + $(CAS_KERNEL) -lTKBRep -lTKG2d -lTKG3d -lTKTopAlgo -lTKGeomBase -lTKGeomAlgo \ + $(MED_LDFLAGS) -lSalomeIDLMED \ + $(SMESH_LDFLAGS) -lSMESHimpl -lSMESHEngine -lSMESHDS -lSMDS -lStdMeshers \ + $(KERNEL_LDFLAGS) -lSalomeGenericObj -lSALOMELocalTrace -lSALOMEBasics diff --git a/src/GHS3DPlugin_Defs.hxx b/src/GHS3DPlugin_Defs.hxx deleted file mode 100644 index 0d9f927..0000000 --- a/src/GHS3DPlugin_Defs.hxx +++ /dev/null @@ -1,37 +0,0 @@ -// Copyright (C) 2004-2010 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -//============================================================================= -// File : GHS3DPlugin_Defs.hxx -// Author : Alexander A. BORODIN -// -#ifndef _GHS3DPlugin_DEFS_HXX_ -#define _GHS3DPlugin_DEFS_HXX_ - -#ifdef WIN32 - #if defined GHS3DPLUGIN_EXPORTS || defined GHS3DEngine_EXPORTS - #define GHS3DPLUGIN_EXPORT __declspec( dllexport ) - #else - #define GHS3DPLUGIN_EXPORT __declspec( dllimport ) - #endif -#else - #define GHS3DPLUGIN_EXPORT -#endif - -#endif diff --git a/src/GHS3DPlugin_GHS3D.cxx b/src/GHS3DPlugin_GHS3D.cxx deleted file mode 100644 index 6393c23..0000000 --- a/src/GHS3DPlugin_GHS3D.cxx +++ /dev/null @@ -1,2153 +0,0 @@ -// Copyright (C) 2004-2010 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -//============================================================================= -// File : GHS3DPlugin_GHS3D.cxx -// Created : -// Author : Edward AGAPOV, modified by Lioka RAZAFINDRAZAKA (CEA) 09/02/2007 -// Project : SALOME -//============================================================================= -// -#include "GHS3DPlugin_GHS3D.hxx" -#include "GHS3DPlugin_Hypothesis.hxx" - - -#include - -#include "SMESH_Gen.hxx" -#include "SMESH_Mesh.hxx" -#include "SMESH_Comment.hxx" -#include "SMESH_MesherHelper.hxx" -#include "SMESH_MeshEditor.hxx" - -#include "SMDS_MeshElement.hxx" -#include "SMDS_MeshNode.hxx" -#include "SMDS_FaceOfNodes.hxx" -#include "SMDS_VolumeOfNodes.hxx" - -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -//#include -#include -#include -#include - -#include "utilities.h" - -#ifdef WIN32 -#include -#else -#include -#endif - -using namespace std; - -//#include - - -#define castToNode(n) static_cast( n ); - -#ifdef _DEBUG_ -#define DUMP(txt) \ -// std::cout << txt -#else -#define DUMP(txt) -#endif - -extern "C" -{ -#ifndef WNT -#include -#include -#endif -#include -#include -} - -#define HOLE_ID -1 - -typedef const list TTriaList; - -static void removeFile( const TCollection_AsciiString& fileName ) -{ - try { - OSD_File( fileName ).Remove(); - } - catch ( Standard_ProgramError ) { - MESSAGE("Can't remove file: " << fileName.ToCString() << " ; file does not exist or permission denied"); - } -} - -//============================================================================= -/*! - * - */ -//============================================================================= - -GHS3DPlugin_GHS3D::GHS3DPlugin_GHS3D(int hypId, int studyId, SMESH_Gen* gen) - : SMESH_3D_Algo(hypId, studyId, 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; - _compatibleHypothesis.push_back("GHS3D_Parameters"); - _compatibleHypothesis.push_back( StdMeshers_ViscousLayers::GetHypType() ); - _requireShape = false; // can work without shape -} - -//============================================================================= -/*! - * - */ -//============================================================================= - -GHS3DPlugin_GHS3D::~GHS3DPlugin_GHS3D() -{ - MESSAGE("GHS3DPlugin_GHS3D::~GHS3DPlugin_GHS3D"); -} - -//============================================================================= -/*! - * - */ -//============================================================================= - -bool GHS3DPlugin_GHS3D::CheckHypothesis ( SMESH_Mesh& aMesh, - const TopoDS_Shape& aShape, - Hypothesis_Status& aStatus ) -{ - aStatus = SMESH_Hypothesis::HYP_OK; - - _hyp = 0; - _viscousLayersHyp = 0; - _keepFiles = false; - - const list & hyps = - GetUsedHypothesis(aMesh, aShape, /*ignoreAuxiliary=*/false); - list ::const_iterator h = hyps.begin(); - for ( ; h != hyps.end(); ++h ) - { - if ( !_hyp ) - _hyp = dynamic_cast< const GHS3DPlugin_Hypothesis*> ( *h ); - if ( !_viscousLayersHyp ) - _viscousLayersHyp = dynamic_cast< const StdMeshers_ViscousLayers*> ( *h ); - } - if ( _hyp ) - _keepFiles = _hyp->GetKeepFiles(); - - 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, - TopAbs_State * state = 0) -{ - gp_XYZ aPnt(0,0,0); - int j, iShape, nbNode = 4; - - for ( j=0; jX(), aNode[j]->Y(), aNode[j]->Z() ); - if ( aNode[j]->GetPosition()->GetTypeOfPosition() == SMDS_TOP_3DSPACE ) { - aPnt = p; - break; - } - aPnt += p / nbNode; - } - - BRepClass3d_SolidClassifier SC (aShape, aPnt, Precision::Confusion()); - if (state) *state = SC.State(); - if ( SC.State() != TopAbs_IN || aShape.IsNull() || aShape.ShapeType() != TopAbs_SOLID) { - for (iShape = 0; iShape < nShape; iShape++) { - aShape = shape[iShape]; - if ( !( aPnt.X() < box[iShape][0] || box[iShape][1] < aPnt.X() || - aPnt.Y() < box[iShape][2] || box[iShape][3] < aPnt.Y() || - aPnt.Z() < box[iShape][4] || box[iShape][5] < aPnt.Z()) ) { - BRepClass3d_SolidClassifier SC (aShape, aPnt, Precision::Confusion()); - if (state) *state = SC.State(); - if (SC.State() == TopAbs_IN) - break; - } - } - } - return aShape; -} - -//======================================================================= -//function : readMapIntLine -//purpose : -//======================================================================= - -static char* readMapIntLine(char* ptr, int tab[]) { - long int intVal; - std::cout << std::endl; - - for ( int i=0; i<17; i++ ) { - intVal = strtol(ptr, &ptr, 10); - if ( i < 3 ) - tab[i] = intVal; - } - return ptr; -} - -//======================================================================= -//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 : -//======================================================================= - -static bool writeFaces (ofstream & theFile, - const SMESH_ProxyMesh& theMesh, - const TopoDS_Shape& theShape, - const map & theSmdsToGhs3dIdMap) -{ - // 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 - - TopoDS_Shape aShape; - const SMESHDS_SubMesh* theSubMesh; - const SMDS_MeshElement* aFace; - const char* space = " "; - const int dummyint = 0; - map::const_iterator itOnMap; - SMDS_ElemIteratorPtr itOnSubMesh, itOnSubFace; - int nbNodes, aSmdsID; - - // count triangles bound to geometry - int nbTriangles = 0; - - TopTools_IndexedMapOfShape facesMap; - TopExp::MapShapes( theShape, TopAbs_FACE, facesMap ); - - for ( int i = 1; i <= facesMap.Extent(); ++i ) - if (( theSubMesh = theMesh.GetSubMesh( facesMap(i)))) - nbTriangles += theSubMesh->NbElements(); - - std::cout << " " << facesMap.Extent() << " shapes of 2D dimension" << std::endl; - std::cout << std::endl; - - theFile << space << nbTriangles << space << dummyint << std::endl; - - for ( int i = 1; i <= facesMap.Extent(); i++ ) - { - aShape = facesMap(i); - theSubMesh = theMesh.GetSubMesh(aShape); - if ( !theSubMesh ) continue; - 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 ); - // if ( itOnMap == theSmdsToGhs3dIdMap.end() ) { - // cout << "not found node: " << aSmdsID << endl; - // return false; - // } - 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 << std::endl; - } - } - - return true; -} - -//======================================================================= -//function : writeFaces -//purpose : Write Faces in case if generate 3D mesh w/o geometry -//======================================================================= - -static bool writeFaces (ofstream & theFile, - const SMESH_ProxyMesh& 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 nbNodes, nbTriangles = 0; - map< const SMDS_MeshNode*,int >::iterator it; - SMDS_ElemIteratorPtr nodeIt; - const SMDS_MeshElement* elem; - - const char* space = " "; - const int dummyint = 0; - - // count faces - nbTriangles = theMesh.NbFaces(); - - if ( nbTriangles == 0 ) - return false; - - std::cout << "The initial 2D mesh contains " << nbTriangles << " faces and "; - - // NB_ELEMS DUMMY_INT - theFile << space << nbTriangles << space << dummyint << std::endl; - - - map aNodeToGhs3dIdMap; - - // Loop from 1 to NB_ELEMS - - SMDS_ElemIteratorPtr eIt = theMesh.GetFaces(); - while ( eIt->more() ) - { - elem = eIt->next(); - // NB_NODES PER FACE - nbNodes = elem->NbNodes(); - theFile << space << nbNodes; - - // NODE_NB_1 NODE_NB_2 ... - nodeIt = elem->nodesIterator(); - while ( nodeIt->more() ) - { - // find GHS3D ID - 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 - for ( int i=0; i<=nbNodes; i++) - theFile << space << dummyint; - theFile << std::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; -} - -//======================================================================= -//function : writePoints -//purpose : -//======================================================================= - -static bool writePoints (ofstream & theFile, - SMESH_MesherHelper& theHelper, - map & theSmdsToGhs3dIdMap, - map & theGhs3dIdToNodeMap, - map,double> & theEnforcedVertices) -{ - // record structure: - // - // NB_NODES - // Loop from 1 to NB_NODES - // X Y Z DUMMY_INT - - SMESHDS_Mesh * theMesh = theHelper.GetMeshDS(); - int nbNodes = theMesh->NbNodes(); - if ( nbNodes == 0 ) - return false; - int nbEnforcedVertices = theEnforcedVertices.size(); - - // Issue 020674: EDF 870 SMESH: Mesh generated by Netgen not usable by GHS3D - // The problem is in nodes on degenerated edges, we need to skip them - if ( theHelper.HasDegeneratedEdges() ) - { - // here we decrease total nb of nodes by nb of nodes on degenerated edges - set checkedSM; - for (TopExp_Explorer e(theMesh->ShapeToMesh(), TopAbs_EDGE ); e.More(); e.Next()) - { - SMESH_subMesh* sm = theHelper.GetMesh()->GetSubMesh( e.Current() ); - if ( checkedSM.insert( sm->GetId() ).second && theHelper.IsDegenShape(sm->GetId() )) { - if ( sm->GetSubMeshDS() ) - nbNodes -= sm->GetSubMeshDS()->NbNodes(); - } - } - } - const char* space = " "; - const int dummyint = 0; - - int aGhs3dID = 1; - SMDS_NodeIteratorPtr it = theMesh->nodesIterator(); - const SMDS_MeshNode* node; - - // NB_NODES - std::cout << std::endl; - std::cout << "The initial 2D mesh contains :" << std::endl; - std::cout << " " << nbNodes << " nodes" << std::endl; - if (nbEnforcedVertices > 0) { - std::cout << " " << nbEnforcedVertices << " enforced vertices" << std::endl; - } - std::cout << std::endl; - std::cout << "Start writing in 'points' file ..." << std::endl; - theFile << space << nbNodes << std::endl; - - // Loop from 1 to NB_NODES - - while ( it->more() ) - { - node = it->next(); - if ( node->GetPosition()->GetTypeOfPosition() == SMDS_TOP_EDGE && - theHelper.IsDegenShape( node->getshapeId() )) // Issue 020674 - continue; - - theSmdsToGhs3dIdMap.insert( make_pair( node->GetID(), aGhs3dID )); - theGhs3dIdToNodeMap.insert( make_pair( aGhs3dID, node )); - aGhs3dID++; - - // X Y Z DUMMY_INT - theFile - << space << node->X() - << space << node->Y() - << space << node->Z() - << space << dummyint; - - theFile << std::endl; - - } - - // Iterate over the enforced vertices - GHS3DPlugin_Hypothesis::TEnforcedVertexValues::const_iterator vertexIt; - const TopoDS_Shape shapeToMesh = theMesh->ShapeToMesh(); - for(vertexIt = theEnforcedVertices.begin() ; vertexIt != theEnforcedVertices.end() ; ++vertexIt) { - double x = vertexIt->first[0]; - double y = vertexIt->first[1]; - double z = vertexIt->first[2]; - // Test if point is inside shape to mesh - gp_Pnt myPoint(x,y,z); - BRepClass3d_SolidClassifier scl(shapeToMesh); - scl.Perform(myPoint, 1e-7); - TopAbs_State result = scl.State(); - if ( result == TopAbs_IN ) { - MESSAGE("Adding enforced vertex (" << x << "," << y <<"," << z << ") = " << vertexIt->second); - // X Y Z PHY_SIZE DUMMY_INT - theFile - << space << x - << space << y - << space << z - << space << vertexIt->second - << space << dummyint; - - theFile << std::endl; - } - else - MESSAGE("Enforced vertex (" << x << "," << y <<"," << z << ") is not inside the geometry: it was not added "); - } - - - std::cout << std::endl; - std::cout << "End writing in 'points' file." << std::endl; - - return true; -} - -//======================================================================= -//function : writePoints -//purpose : -//======================================================================= - -static bool writePoints (ofstream & theFile, - SMESH_Mesh * theMesh, - const vector & theNodeByGhs3dId, - map,double> & theEnforcedVertices) -{ - // record structure: - // - // NB_NODES - // Loop from 1 to NB_NODES - // X Y Z DUMMY_INT - - int nbNodes = theNodeByGhs3dId.size(); - if ( nbNodes == 0 ) - return false; - - int nbEnforcedVertices = theEnforcedVertices.size(); - - const char* space = " "; - const int dummyint = 0; - - const SMDS_MeshNode* node; - - // NB_NODES - std::cout << std::endl; - std::cout << "The initial 2D mesh contains :" << std::endl; - std::cout << " " << nbNodes << " nodes" << std::endl; - std::cout << " " << nbEnforcedVertices << " enforced vertices" << std::endl; - std::cout << std::endl; - std::cout << "Start writing in 'points' file ..." << std::endl; - theFile << space << nbNodes << std::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 << std::endl; - - } - - // Iterate over the enforced vertices - GHS3DPlugin_Hypothesis::TEnforcedVertexValues::const_iterator vertexIt; - auto_ptr< SMESH_ElementSearcher > pntCls ( SMESH_MeshEditor( theMesh ).GetElementSearcher()); - for(vertexIt = theEnforcedVertices.begin() ; vertexIt != theEnforcedVertices.end() ; ++vertexIt) { - double x = vertexIt->first[0]; - double y = vertexIt->first[1]; - double z = vertexIt->first[2]; - // Test if point is inside shape to mesh - gp_Pnt myPoint(x,y,z); - TopAbs_State result = pntCls->GetPointState( myPoint ); - if ( result == TopAbs_IN ) { - std::cout << "Adding enforced vertex (" << x << "," << y <<"," << z << ") = " << vertexIt->second << std::endl; - - // X Y Z PHY_SIZE DUMMY_INT - theFile - << space << x - << space << y - << space << z - << space << vertexIt->second - << space << dummyint; - - theFile << std::endl; - } - } - std::cout << std::endl; - std::cout << "End writing in 'points' file." << std::endl; - - 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 : -//======================================================================= - -static bool readResultFile(const int fileOpen, -#ifdef WNT - const char* fileName, -#endif - SMESH_Mesh& theMesh, - TopoDS_Shape tabShape[], - double** tabBox, - const int nbShape, - map & theGhs3dIdToNodeMap, - bool toMeshHoles, - int nbEnforcedVertices) -{ - MESSAGE("GHS3DPlugin_GHS3D::readResultFile()"); - Kernel_Utils::Localizer loc; - struct stat status; - size_t length; - - char *ptr, *mapPtr; - char *tetraPtr; - char *shapePtr; - - SMESHDS_Mesh* theMeshDS = theMesh.GetMeshDS(); - - int fileStat; - int nbElems, nbNodes, nbInputNodes; - int nodeId/*, triangleId*/; - int nbTriangle; - int ID, shapeID, ghs3dShapeID; - int IdShapeRef = 1; - int compoundID = - nbShape ? theMeshDS->ShapeToIndex( tabShape[0] ) : 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; -#ifdef _DEBUG_ - set shapeIDs; -#endif - - // Read the file state - fileStat = fstat(fileOpen, &status); - length = status.st_size; - - // Mapping the result file into memory -#ifdef WNT - HANDLE fd = CreateFile(fileName, 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; - - nbElems = tab[0]; - nbNodes = tab[1]; - nbInputNodes = tab[2]; - - nodeAssigne = new int[ nbNodes+1 ]; - - if (nbShape > 0) - aSolid = tabShape[0]; - - // Reading the nodeId - for (int i=0; i < 4*nbElems; i++) - nodeId = strtol(ptr, &ptr, 10); - - MESSAGE("nbInputNodes: "< (nbInputNodes-nbEnforcedVertices) ) { - // Creating SMESH nodes - // - for enforced vertices - // - for vertices of forced edges - // - for ghs3d nodes - nodeAssigne[ iNode ] = 0; - aNewNode = theMeshDS->AddNode( coord[0],coord[1],coord[2] ); - theGhs3dIdToNodeMap.insert(theGhs3dIdToNodeMap.end(), make_pair( iNode, aNewNode )); - } - } - - // Reading the number of triangles which corresponds to the number of sub-domains - nbTriangle = strtol(ptr, &ptr, 10); - - tabID = new int[nbTriangle]; - for (int i=0; i < nbTriangle; i++) { - tabID[i] = 0; - // find the solid corresponding to GHS3D sub-domain following - // the technique proposed in GHS3D manual in chapter - // "B.4 Subdomain (sub-region) assignment" - int nodeId1 = strtol(ptr, &ptr, 10); - int nodeId2 = strtol(ptr, &ptr, 10); - int nodeId3 = strtol(ptr, &ptr, 10); - if ( nbTriangle > 1 ) { - 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 - } - } - } - - shapePtr = ptr; - - if ( nbTriangle <= nbShape ) // no holes - toMeshHoles = true; // not avoid creating tetras in holes - - // 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; - } - // 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 - //aTet = theMeshDS->AddVolume( node[1], node[0], node[2], node[3] ); - if ( nbTriangle > 1 ) { - shapeID = HOLE_ID; // negative shapeID means not to create tetras if !toMeshHoles - ghs3dShapeID = strtol(shapePtr, &shapePtr, 10) - IdShapeRef; - if ( tabID[ ghs3dShapeID ] == 0 ) { - TopAbs_State state; - aSolid = findShape(node, aSolid, tabShape, tabBox, nbShape, &state); - if ( toMeshHoles || state == TopAbs_IN ) - shapeID = theMeshDS->ShapeToIndex( aSolid ); - tabID[ ghs3dShapeID ] = shapeID; - } - else - shapeID = tabID[ ghs3dShapeID ]; - } - 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 - shapeID = 0; - for ( int i=0; i<4 && shapeID==0; i++ ) { - if ( nodeAssigne[ nodeID[i] ] == 1 && - node[i]->GetPosition()->GetTypeOfPosition() == SMDS_TOP_3DSPACE && - node[i]->getshapeId() > 1 ) - { - shapeID = node[i]->getshapeId(); - } - } - if ( shapeID==0 ) { - aSolid = findShape(node, aSolid, tabShape, tabBox, nbShape); - shapeID = theMeshDS->ShapeToIndex( aSolid ); - } - } - // set new nodes and tetrahedron onto the shape - for ( int i=0; i<4; i++ ) { - if ( nodeAssigne[ nodeID[i] ] == 0 ) { - if ( shapeID != HOLE_ID ) - theMeshDS->SetNodeInVolume( node[i], shapeID ); - nodeAssigne[ nodeID[i] ] = shapeID; - } - } - if ( toMeshHoles || shapeID != HOLE_ID ) { - aTet = theMeshDS->AddVolume( node[1], node[0], node[2], node[3] ); - theMeshDS->SetMeshElementOnShape( aTet, shapeID ); - } -#ifdef _DEBUG_ - shapeIDs.insert( shapeID ); -#endif - } - // Remove nodes of tetras inside holes if !toMeshHoles - if ( !toMeshHoles ) { - itOnNode = theGhs3dIdToNodeMap.find( nbInputNodes ); - for ( ; itOnNode != theGhs3dIdToNodeMap.end(); ++itOnNode) { - ID = itOnNode->first; - if ( nodeAssigne[ ID ] == HOLE_ID ) - theMeshDS->RemoveFreeNode( itOnNode->second, 0 ); - } - } - - if ( nbElems ) - cout << nbElems << " tetrahedrons have been associated to " << nbShape << " shapes" << endl; -#ifdef WNT - UnmapViewOfFile(mapPtr); - CloseHandle(hMapObject); - CloseHandle(fd); -#else - munmap(mapPtr, length); -#endif - close(fileOpen); - - delete [] tab; - delete [] tabID; - delete [] nodeID; - delete [] coord; - delete [] node; - delete [] nodeAssigne; - -#ifdef _DEBUG_ - shapeIDs.erase(-1); - if ( shapeIDs.size() != nbShape ) { - std::cout << "Only " << shapeIDs.size() << " solids of " << nbShape << " found" << std::endl; - for (int i=0; iShapeToIndex( tabShape[i] ); - if ( shapeIDs.find( shapeID ) == shapeIDs.end() ) - std::cout << " Solid #" << shapeID << " not found" << std::endl; - } - } -#endif - - return true; -} - -//======================================================================= -//function : readResultFile -//purpose : -//======================================================================= - -static bool readResultFile(const int fileOpen, -#ifdef WNT - const char* fileName, -#endif - SMESH_Mesh& theMesh, - TopoDS_Shape aSolid, - vector & theNodeByGhs3dId, - int nbEnforcedVertices) -{ - SMESHDS_Mesh* theMeshDS = theMesh.GetMeshDS(); - - Kernel_Utils::Localizer loc; - 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; - - int *tab; - double *coord; - const SMDS_MeshNode **node; - - tab = new int[3]; - coord = new double[3]; - node = new const SMDS_MeshNode*[4]; - - SMDS_MeshNode * aNewNode; - map ::iterator IdNode; - SMDS_MeshElement* aTet; - - // Read the file state - fileStat = fstat(fileOpen, &status); - length = status.st_size; - - // Mapping the result file into memory -#ifdef WNT - HANDLE fd = CreateFile(fileName, 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; - - nbElems = tab[0]; - nbNodes = tab[1]; - nbInputNodes = tab[2]; - - theNodeByGhs3dId.resize( nbNodes ); - - // Reading the nodeId - for (int i=0; i < 4*nbElems; i++) - nodeId = strtol(ptr, &ptr, 10); - - // Issue 0020682. Avoid creating nodes and tetras at place where - // volumic elements already exist - SMESH_ElementSearcher* elemSearcher = 0; - vector< const SMDS_MeshElement* > foundVolumes; - if ( theMesh.NbVolumes() > 0 ) - elemSearcher = SMESH_MeshEditor( &theMesh ).GetElementSearcher(); - - // Reading the nodeCoord and update the nodeMap - shapeID = theMeshDS->ShapeToIndex( aSolid ); - for (int iNode=0; iNode < nbNodes; iNode++) { - for (int iCoor=0; iCoor < 3; iCoor++) - coord[ iCoor ] = strtod(ptr, &ptr); - if ((iNode+1) > (nbInputNodes-nbEnforcedVertices)) { - // Issue 0020682. Avoid creating nodes and tetras at place where - // volumic elements already exist - if ( elemSearcher && - elemSearcher->FindElementsByPoint( gp_Pnt(coord[0],coord[1],coord[2]), - SMDSAbs_Volume, foundVolumes )) - { - theNodeByGhs3dId[ iNode ] = 0; - } - else - { - aNewNode = theMeshDS->AddNode( coord[0],coord[1],coord[2] ); - theMeshDS->SetNodeInVolume( aNewNode, shapeID ); - theNodeByGhs3dId[ iNode ] = aNewNode; - } - } - } - - // Reading the triangles - nbTriangle = strtol(ptr, &ptr, 10); - - for (int i=0; i < 3*nbTriangle; i++) - triangleId = strtol(ptr, &ptr, 10); - - shapePtr = ptr; - - // Associating the tetrahedrons to the shapes - for (int iElem = 0; iElem < nbElems; iElem++) { - for (int iNode = 0; iNode < 4; iNode++) { - ID = strtol(tetraPtr, &tetraPtr, 10); - node[ iNode ] = theNodeByGhs3dId[ ID-1 ]; - } - if ( elemSearcher ) - { - // Issue 0020682. Avoid creating nodes and tetras at place where - // volumic elements already exist - if ( !node[1] || !node[0] || !node[2] || !node[3] ) - continue; - if ( elemSearcher->FindElementsByPoint(( SMESH_TNodeXYZ(node[0]) + - SMESH_TNodeXYZ(node[1]) + - SMESH_TNodeXYZ(node[2]) + - SMESH_TNodeXYZ(node[3]) ) / 4., - SMDSAbs_Volume, foundVolumes )) - continue; - } - aTet = theMeshDS->AddVolume( node[1], node[0], node[2], node[3] ); - shapeID = theMeshDS->ShapeToIndex( aSolid ); - theMeshDS->SetMeshElementOnShape( aTet, shapeID ); - } - if ( nbElems ) - cout << nbElems << " tetrahedrons have been associated to " << nbTriangle << " shapes" << endl; -#ifdef WNT - UnmapViewOfFile(mapPtr); - CloseHandle(hMapObject); - CloseHandle(fd); -#else - munmap(mapPtr, length); -#endif - close(fileOpen); - - delete [] tab; - delete [] coord; - delete [] node; - - return true; -} - -//============================================================================= -/*! - *Here we are going to use the GHS3D mesher - */ -//============================================================================= - -bool GHS3DPlugin_GHS3D::Compute(SMESH_Mesh& theMesh, - const TopoDS_Shape& theShape) -{ - bool Ok(false); - //SMESHDS_Mesh* meshDS = theMesh.GetMeshDS(); - - // we count the number of shapes - // _nbShape = countShape( meshDS, TopAbs_SOLID ); -- 0020330: Pb with ghs3d as a submesh - _nbShape = 0; - TopExp_Explorer expBox ( theShape, TopAbs_SOLID ); - for ( ; expBox.More(); expBox.Next() ) - _nbShape++; - - // 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; - - for (expBox.ReInit(); 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++; - } - - // a unique working file name - // to avoid access to the same files by eg different users - TCollection_AsciiString aGenericName - = (char*) GHS3DPlugin_Hypothesis::GetFileName(_hyp).c_str(); - - 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 = - aFacesFile.rdbuf()->is_open() && aPointsFile.rdbuf()->is_open(); - if (!Ok) { - INFOS( "Can't write into " << aFacesFileName); - return error(SMESH_Comment("Can't write into ") << aFacesFileName); - } - map aSmdsToGhs3dIdMap; - map aGhs3dIdToNodeMap; - map,double> enforcedVertices; - int nbEnforcedVertices = 0; - try { - enforcedVertices = GHS3DPlugin_Hypothesis::GetEnforcedVertices(_hyp); - nbEnforcedVertices = enforcedVertices.size(); - } - catch(...) { - } - - SMESH_MesherHelper helper( theMesh ); - helper.SetSubShape( theShape ); - - { - SMESH_ProxyMesh::Ptr proxyMesh( new SMESH_ProxyMesh( theMesh )); - - // make prisms on quadrangles - if ( theMesh.NbQuadrangles() > 0 ) - { - vector components; - for (expBox.ReInit(); expBox.More(); expBox.Next()) - { - if ( _viscousLayersHyp ) - { - proxyMesh = _viscousLayersHyp->Compute( theMesh, expBox.Current() ); - if ( !proxyMesh ) - return false; - } - StdMeshers_QuadToTriaAdaptor* q2t = new StdMeshers_QuadToTriaAdaptor; - q2t->Compute( theMesh, expBox.Current(), proxyMesh.get() ); - components.push_back( SMESH_ProxyMesh::Ptr( q2t )); - } - proxyMesh.reset( new SMESH_ProxyMesh( components )); - } - // build viscous layers - else if ( _viscousLayersHyp ) - { - proxyMesh = _viscousLayersHyp->Compute( theMesh, theShape ); - if ( !proxyMesh ) - return false; - } - - Ok = (writePoints( aPointsFile, helper, aSmdsToGhs3dIdMap, aGhs3dIdToNodeMap, enforcedVertices) - && - writeFaces ( aFacesFile, *proxyMesh, theShape, aSmdsToGhs3dIdMap )); - } - - // Write aSmdsToGhs3dIdMap to temp file - TCollection_AsciiString aSmdsToGhs3dIdMapFileName; - aSmdsToGhs3dIdMapFileName = aGenericName + ".ids"; // ids relation - ofstream aIdsFile ( aSmdsToGhs3dIdMapFileName.ToCString() , ios::out); - Ok = - aIdsFile.rdbuf()->is_open(); - if (!Ok) { - INFOS( "Can't write into " << aSmdsToGhs3dIdMapFileName); - return error(SMESH_Comment("Can't write into ") << aSmdsToGhs3dIdMapFileName); - } - aIdsFile << "Smds Ghs3d" << std::endl; - map ::const_iterator myit; - for (myit=aSmdsToGhs3dIdMap.begin() ; myit != aSmdsToGhs3dIdMap.end() ; ++myit) { - aIdsFile << myit->first << " " << myit->second << std::endl; - } - - aFacesFile.close(); - aPointsFile.close(); - aIdsFile.close(); - - if ( ! Ok ) { - if ( !_keepFiles ) { - removeFile( aFacesFileName ); - removeFile( aPointsFileName ); - removeFile( aSmdsToGhs3dIdMapFileName ); - } - return error(COMPERR_BAD_INPUT_MESH); - } - removeFile( aResultFileName ); // needed for boundary recovery module usage - - // ----------------- - // run ghs3d mesher - // ----------------- - - TCollection_AsciiString cmd( (char*)GHS3DPlugin_Hypothesis::CommandToRun( _hyp ).c_str() ); - cmd += TCollection_AsciiString(" -f ") + aGenericName; // file to read - cmd += TCollection_AsciiString(" 1>" ) + aLogFileName; // dump into file - - std::cout << std::endl; - std::cout << "Ghs3d execution..." << std::endl; - std::cout << cmd << std::endl; - - system( cmd.ToCString() ); // run - - std::cout << std::endl; - std::cout << "End of Ghs3d execution !" << std::endl; - - // -------------- - // read a result - // -------------- - - // Mapping the result file - - int fileOpen; - 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 { - bool toMeshHoles = - _hyp ? _hyp->GetToMeshHoles(true) : GHS3DPlugin_Hypothesis::DefaultMeshHoles(); - Ok = readResultFile( fileOpen, -#ifdef WNT - aResultFileName.ToCString(), -#endif - theMesh, tabShape, tabBox, _nbShape, aGhs3dIdToNodeMap, - toMeshHoles, nbEnforcedVertices ); - } - - // --------------------- - // remove working files - // --------------------- - - if ( Ok ) - { - if ( !_keepFiles ) - removeFile( aLogFileName ); - } - else if ( OSD_File( aLogFileName ).Size() > 0 ) - { - // get problem description from the log file - _Ghs2smdsConvertor conv( aGhs3dIdToNodeMap ); - storeErrorDescription( aLogFileName, conv ); - } - else - { - // the log file is empty - removeFile( aLogFileName ); - INFOS( "GHS3D Error, command '" << cmd.ToCString() << "' failed" ); - error(COMPERR_ALGO_FAILED, "ghs3d: command not found" ); - } - - if ( !_keepFiles ) { - removeFile( aFacesFileName ); - removeFile( aPointsFileName ); - removeFile( aResultFileName ); - removeFile( aBadResFileName ); - removeFile( aBbResFileName ); - removeFile( aSmdsToGhs3dIdMapFileName ); - } - std::cout << "<" << aResultFileName.ToCString() << "> GHS3D output file "; - if ( !Ok ) - std::cout << "not "; - std::cout << "treated !" << std::endl; - std::cout << std::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(); - - // a unique working file name - // to avoid access to the same files by eg different users - TCollection_AsciiString aGenericName - = (char*) GHS3DPlugin_Hypothesis::GetFileName(_hyp).c_str(); - - 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 = - aFacesFile.rdbuf()->is_open() && aPointsFile.rdbuf()->is_open(); - - if (!Ok) - return error( SMESH_Comment("Can't write into ") << aPointsFileName); - - GHS3DPlugin_Hypothesis::TEnforcedVertexValues enforcedVertices; - int nbEnforcedVertices = 0; - try { - enforcedVertices = GHS3DPlugin_Hypothesis::GetEnforcedVertices(_hyp); - nbEnforcedVertices = enforcedVertices.size(); - } - catch(...) { - } - - vector aNodeByGhs3dId; - { - SMESH_ProxyMesh::Ptr proxyMesh( new SMESH_ProxyMesh( theMesh )); - if ( theMesh.NbQuadrangles() > 0 ) - { - StdMeshers_QuadToTriaAdaptor* aQuad2Trias = new StdMeshers_QuadToTriaAdaptor; - aQuad2Trias->Compute( theMesh ); - proxyMesh.reset( aQuad2Trias ); - } - - Ok = (writeFaces ( aFacesFile, *proxyMesh, aNodeByGhs3dId ) && - writePoints( aPointsFile, &theMesh, aNodeByGhs3dId,enforcedVertices)); - } - aFacesFile.close(); - aPointsFile.close(); - - if ( ! Ok ) { - if ( !_keepFiles ) { - removeFile( aFacesFileName ); - removeFile( aPointsFileName ); - } - return error(COMPERR_BAD_INPUT_MESH); - } - removeFile( aResultFileName ); // needed for boundary recovery module usage - - // ----------------- - // run ghs3d mesher - // ----------------- - - TCollection_AsciiString cmd = - (char*)GHS3DPlugin_Hypothesis::CommandToRun( _hyp, false ).c_str(); - cmd += TCollection_AsciiString(" -f ") + aGenericName; // file to read - cmd += TCollection_AsciiString(" 1>" ) + aLogFileName; // dump into file - - system( cmd.ToCString() ); // run - - // -------------- - // read a result - // -------------- - int fileOpen; - fileOpen = open( aResultFileName.ToCString(), O_RDONLY); - if ( fileOpen < 0 ) { - std::cout << std::endl; - std::cout << "Error when opening the " << aResultFileName.ToCString() << " file" << std::endl; - std::cout << "Log: " << aLogFileName << std::endl; - std::cout << std::endl; - Ok = false; - } - else { - Ok = readResultFile( fileOpen, -#ifdef WNT - aResultFileName.ToCString(), -#endif - theMesh, theShape ,aNodeByGhs3dId, nbEnforcedVertices ); - } - - // --------------------- - // remove working files - // --------------------- - - if ( Ok ) - { - if ( !_keepFiles ) - removeFile( aLogFileName ); - } - else if ( OSD_File( aLogFileName ).Size() > 0 ) - { - // get problem description from the log file - _Ghs2smdsConvertor conv( aNodeByGhs3dId ); - storeErrorDescription( aLogFileName, conv ); - } - else { - // the log file is empty - removeFile( aLogFileName ); - INFOS( "GHS3D Error, command '" << cmd.ToCString() << "' failed" ); - error(COMPERR_ALGO_FAILED, "ghs3d: command not found" ); - } - - if ( !_keepFiles ) - { - removeFile( aFacesFileName ); - removeFile( aPointsFileName ); - removeFile( aResultFileName ); - removeFile( aBadResFileName ); - removeFile( aBbResFileName ); - } - - return Ok; -} - -//================================================================================ -/*! - * \brief Provide human readable text by error code reported by ghs3d - */ -//================================================================================ - -static string translateError(const int errNum) -{ - switch ( errNum ) { - case 0: - return "The surface mesh includes a face of type other than edge, " - "triangle or quadrilateral. This face type is not supported."; - case 1: - return "Not enough memory for the face table."; - case 2: - return "Not enough memory."; - case 3: - return "Not enough memory."; - case 4: - return "Face is ignored."; - case 5: - return "End of file. Some data are missing in the file."; - case 6: - return "Read error on the file. There are wrong data in the file."; - case 7: - return "the metric file is inadequate (dimension other than 3)."; - case 8: - return "the metric file is inadequate (values not per vertices)."; - case 9: - return "the metric file contains more than one field."; - case 10: - return "the number of values in the \".bb\" (metric file) is incompatible with the expected" - "value of number of mesh vertices in the \".noboite\" file."; - case 12: - return "Too many sub-domains."; - case 13: - return "the number of vertices is negative or null."; - case 14: - return "the number of faces is negative or null."; - case 15: - return "A face has a null vertex."; - case 22: - return "incompatible data."; - case 131: - return "the number of vertices is negative or null."; - case 132: - return "the number of vertices is negative or null (in the \".mesh\" file)."; - case 133: - return "the number of faces is negative or null."; - case 1000: - return "A face appears more than once in the input surface mesh."; - case 1001: - return "An edge appears more than once in the input surface mesh."; - case 1002: - return "A face has a vertex negative or null."; - case 1003: - return "NOT ENOUGH MEMORY."; - case 2000: - return "Not enough available memory."; - case 2002: - return "Some initial points cannot be inserted. The surface mesh is probably very bad " - "in terms of quality or the input list of points is wrong."; - case 2003: - return "Some vertices are too close to one another or coincident."; - case 2004: - return "Some vertices are too close to one another or coincident."; - case 2012: - return "A vertex cannot be inserted."; - case 2014: - return "There are at least two points considered as coincident."; - case 2103: - return "Some vertices are too close to one another or coincident."; - case 3000: - return "The surface mesh regeneration step has failed."; - case 3009: - return "Constrained edge cannot be enforced."; - case 3019: - return "Constrained face cannot be enforced."; - case 3029: - return "Missing faces."; - case 3100: - return "No guess to start the definition of the connected component(s)."; - case 3101: - return "The surface mesh includes at least one hole. The domain is not well defined."; - case 3102: - return "Impossible to define a component."; - case 3103: - return "The surface edge intersects another surface edge."; - case 3104: - return "The surface edge intersects the surface face."; - case 3105: - return "One boundary point lies within a surface face."; - case 3106: - return "One surface edge intersects a surface face."; - case 3107: - return "One boundary point lies within a surface edge."; - case 3108: - return "Insufficient memory ressources detected due to a bad quality surface mesh leading " - "to too many swaps."; - case 3109: - return "Edge is unique (i.e., bounds a hole in the surface)."; - case 3122: - return "Presumably, the surface mesh is not compatible with the domain being processed."; - case 3123: - return "Too many components, too many sub-domain."; - case 3209: - return "The surface mesh includes at least one hole. " - "Therefore there is no domain properly defined."; - case 3300: - return "Statistics."; - case 3400: - return "Statistics."; - case 3500: - return "Warning, it is dramatically tedious to enforce the boundary items."; - case 4000: - return "Not enough memory at this time, nevertheless, the program continues. " - "The expected mesh will be correct but not really as large as required."; - case 4002: - return "see above error code, resulting quality may be poor."; - case 4003: - return "Not enough memory at this time, nevertheless, the program continues (warning)."; - case 8000: - return "Unknown face type."; - case 8005: - case 8006: - return "End of file. Some data are missing in the file."; - case 9000: - return "A too small volume element is detected."; - case 9001: - return "There exists at least a null or negative volume element."; - case 9002: - return "There exist null or negative volume elements."; - case 9003: - return "A too small volume element is detected. A face is considered being degenerated."; - case 9100: - return "Some element is suspected to be very bad shaped or wrong."; - case 9102: - return "A too bad quality face is detected. This face is considered degenerated."; - case 9112: - return "A too bad quality face is detected. This face is degenerated."; - case 9122: - return "Presumably, the surface mesh is not compatible with the domain being processed."; - case 9999: - return "Abnormal error occured, contact hotline."; - case 23600: - return "Not enough memory for the face table."; - case 23601: - return "The algorithm cannot run further. " - "The surface mesh is probably very bad in terms of quality."; - case 23602: - return "Bad vertex number."; - } - return ""; -} - -//================================================================================ -/*! - * \brief Retrieve from a string given number of integers - */ -//================================================================================ - -static char* getIds( char* ptr, int nbIds, vector& ids ) -{ - ids.clear(); - ids.reserve( nbIds ); - while ( nbIds ) - { - while ( !isdigit( *ptr )) ++ptr; - if ( ptr[-1] == '-' ) --ptr; - ids.push_back( strtol( ptr, &ptr, 10 )); - --nbIds; - } - return ptr; -} - -//================================================================================ -/*! - * \brief Retrieve problem description form a log file - * \retval bool - always false - */ -//================================================================================ - -bool GHS3DPlugin_GHS3D::storeErrorDescription(const TCollection_AsciiString& logFile, - const _Ghs2smdsConvertor & toSmdsConvertor ) -{ - // open file -#ifdef WNT - int file = ::_open (logFile.ToCString(), _O_RDONLY|_O_BINARY); -#else - int file = ::open (logFile.ToCString(), O_RDONLY); -#endif - if ( file < 0 ) - return error( SMESH_Comment("See ") << logFile << " for problem description"); - - // get file size -// struct stat status; -// fstat(file, &status); -// size_t length = status.st_size; - off_t length = lseek( file, 0, SEEK_END); - lseek( file, 0, SEEK_SET); - - // read file - vector< char > buf( length ); - int nBytesRead = ::read (file, & buf[0], length); - ::close (file); - char* ptr = & buf[0]; - char* bufEnd = ptr + nBytesRead; - - SMESH_Comment errDescription; - - enum { NODE = 1, EDGE, TRIA, VOL, ID = 1 }; - - // look for errors "ERR #" - - set foundErrorStr; // to avoid reporting same error several times - set elemErrorNums; // not to report different types of errors with bad elements - while ( ++ptr < bufEnd ) - { - if ( strncmp( ptr, "ERR ", 4 ) != 0 ) - continue; - - list badElems; - vector nodeIds; - - ptr += 4; - char* errBeg = ptr; - int errNum = strtol(ptr, &ptr, 10); - switch ( errNum ) { // we treat errors enumerated in [SALOME platform 0019316] issue - case 0015: - // The face number (numfac) with vertices (f 1, f 2, f 3) has a null vertex. - ptr = getIds(ptr, NODE, nodeIds); - ptr = getIds(ptr, TRIA, nodeIds); - badElems.push_back( toSmdsConvertor.getElement(nodeIds)); - break; - case 1000: // ERR 1000 : 1 3 2 - // Face (f 1, f 2, f 3) appears more than once in the input surface mesh. - ptr = getIds(ptr, TRIA, nodeIds); - badElems.push_back( toSmdsConvertor.getElement(nodeIds)); - break; - case 1001: - // Edge (e1, e2) appears more than once in the input surface mesh - ptr = getIds(ptr, EDGE, nodeIds); - badElems.push_back( toSmdsConvertor.getElement(nodeIds)); - break; - case 1002: - // Face (f 1, f 2, f 3) has a vertex negative or null - ptr = getIds(ptr, TRIA, nodeIds); - badElems.push_back( toSmdsConvertor.getElement(nodeIds)); - break; - case 2004: - // Vertex v1 and vertex v2 are too close to one another or coincident (warning). - ptr = getIds(ptr, NODE, nodeIds); - badElems.push_back( toSmdsConvertor.getElement(nodeIds)); - ptr = getIds(ptr, NODE, nodeIds); - badElems.push_back( toSmdsConvertor.getElement(nodeIds)); - break; - case 2012: - // Vertex v1 cannot be inserted (warning). - ptr = getIds(ptr, NODE, nodeIds); - badElems.push_back( toSmdsConvertor.getElement(nodeIds)); - break; - case 2014: - // There are at least two points whose distance is dist, i.e., considered as coincident - case 2103: // ERR 2103 : 16 WITH 3 - // Vertex v1 and vertex v2 are too close to one another or coincident (warning). - ptr = getIds(ptr, NODE, nodeIds); - badElems.push_back( toSmdsConvertor.getElement(nodeIds)); - ptr = getIds(ptr, NODE, nodeIds); - badElems.push_back( toSmdsConvertor.getElement(nodeIds)); - break; - case 3009: - // Constrained edge (e1, e2) cannot be enforced (warning). - ptr = getIds(ptr, EDGE, nodeIds); - badElems.push_back( toSmdsConvertor.getElement(nodeIds)); - break; - case 3019: - // Constrained face (f 1, f 2, f 3) cannot be enforced - ptr = getIds(ptr, TRIA, nodeIds); - badElems.push_back( toSmdsConvertor.getElement(nodeIds)); - break; - case 3103: // ERR 3103 : 1 2 WITH 7 3 - // The surface edge (e1, e2) intersects another surface edge (e3, e4) - ptr = getIds(ptr, EDGE, nodeIds); - badElems.push_back( toSmdsConvertor.getElement(nodeIds)); - ptr = getIds(ptr, EDGE, nodeIds); - badElems.push_back( toSmdsConvertor.getElement(nodeIds)); - break; - case 3104: // ERR 3104 : 9 10 WITH 1 2 3 - // The surface edge (e1, e2) intersects the surface face (f 1, f 2, f 3) - ptr = getIds(ptr, EDGE, nodeIds); - badElems.push_back( toSmdsConvertor.getElement(nodeIds)); - ptr = getIds(ptr, TRIA, nodeIds); - badElems.push_back( toSmdsConvertor.getElement(nodeIds)); - break; - case 3105: // ERR 3105 : 8 IN 2 3 5 - // One boundary point (say p1) lies within a surface face (f 1, f 2, f 3) - ptr = getIds(ptr, NODE, nodeIds); - badElems.push_back( toSmdsConvertor.getElement(nodeIds)); - ptr = getIds(ptr, TRIA, nodeIds); - badElems.push_back( toSmdsConvertor.getElement(nodeIds)); - break; - case 3106: - // One surface edge (say e1, e2) intersects a surface face (f 1, f 2, f 3) - ptr = getIds(ptr, EDGE, nodeIds); - badElems.push_back( toSmdsConvertor.getElement(nodeIds)); - ptr = getIds(ptr, TRIA, nodeIds); - badElems.push_back( toSmdsConvertor.getElement(nodeIds)); - break; - case 3107: // ERR 3107 : 2 IN 4 1 - // One boundary point (say p1) lies within a surface edge (e1, e2) (stop). - ptr = getIds(ptr, NODE, nodeIds); - badElems.push_back( toSmdsConvertor.getElement(nodeIds)); - ptr = getIds(ptr, EDGE, nodeIds); - badElems.push_back( toSmdsConvertor.getElement(nodeIds)); - break; - case 3109: // ERR 3109 : EDGE 5 6 UNIQUE - // Edge (e1, e2) is unique (i.e., bounds a hole in the surface) - ptr = getIds(ptr, EDGE, nodeIds); - badElems.push_back( toSmdsConvertor.getElement(nodeIds)); - break; - case 9000: // ERR 9000 - // ELEMENT 261 WITH VERTICES : 7 396 -8 242 - // VOLUME : -1.11325045E+11 W.R.T. EPSILON 0. - // A too small volume element is detected. Are reported the index of the element, - // its four vertex indices, its volume and the tolerance threshold value - ptr = getIds(ptr, ID, nodeIds); - ptr = getIds(ptr, VOL, nodeIds); - badElems.push_back( toSmdsConvertor.getElement(nodeIds)); - // even if all nodes found, volume it most probably invisible, - // add its faces to demenstrate it anyhow - { - vector faceNodes( nodeIds.begin(), --nodeIds.end() ); // 012 - badElems.push_back( toSmdsConvertor.getElement(faceNodes)); - faceNodes[2] = nodeIds[3]; // 013 - badElems.push_back( toSmdsConvertor.getElement(faceNodes)); - faceNodes[1] = nodeIds[2]; // 023 - badElems.push_back( toSmdsConvertor.getElement(faceNodes)); - faceNodes[0] = nodeIds[1]; // 123 - badElems.push_back( toSmdsConvertor.getElement(faceNodes)); - } - break; - case 9001: // ERR 9001 - // %% NUMBER OF NEGATIVE VOLUME TETS : 1 - // %% THE LARGEST NEGATIVE TET : 1.75376581E+11 - // %% NUMBER OF NULL VOLUME TETS : 0 - // There exists at least a null or negative volume element - break; - case 9002: - // There exist n null or negative volume elements - break; - case 9003: - // A too small volume element is detected - break; - case 9102: - // A too bad quality face is detected. This face is considered degenerated, - // its index, its three vertex indices together with its quality value are reported - break; // same as next - case 9112: // ERR 9112 - // FACE 2 WITH VERTICES : 4 2 5 - // SMALL INRADIUS : 0. - // A too bad quality face is detected. This face is degenerated, - // its index, its three vertex indices together with its inradius are reported - ptr = getIds(ptr, ID, nodeIds); - ptr = getIds(ptr, TRIA, nodeIds); - badElems.push_back( toSmdsConvertor.getElement(nodeIds)); - // add triangle edges as it most probably has zero area and hence invisible - { - vector edgeNodes(2); - edgeNodes[0] = nodeIds[0]; edgeNodes[1] = nodeIds[1]; // 0-1 - badElems.push_back( toSmdsConvertor.getElement(edgeNodes)); - edgeNodes[1] = nodeIds[2]; // 0-2 - badElems.push_back( toSmdsConvertor.getElement(edgeNodes)); - edgeNodes[0] = nodeIds[1]; // 1-2 - badElems.push_back( toSmdsConvertor.getElement(edgeNodes)); - } - break; - } - - bool isNewError = foundErrorStr.insert( string( errBeg, ptr )).second; - if ( !isNewError ) - continue; // not to report same error several times - -// const SMDS_MeshElement* nullElem = 0; -// bool allElemsOk = ( find( badElems.begin(), badElems.end(), nullElem) == badElems.end()); - -// if ( allElemsOk && !badElems.empty() && !elemErrorNums.empty() ) { -// bool oneMoreErrorType = elemErrorNums.insert( errNum ).second; -// if ( oneMoreErrorType ) -// continue; // not to report different types of errors with bad elements -// } - - // store bad elements - //if ( allElemsOk ) { - list::iterator elem = badElems.begin(); - for ( ; elem != badElems.end(); ++elem ) - addBadInputElement( *elem ); - //} - - // make error text - string text = translateError( errNum ); - if ( errDescription.find( text ) == text.npos ) { - if ( !errDescription.empty() ) - errDescription << "\n"; - errDescription << text; - } - - } // end while - - if ( errDescription.empty() ) { // no errors found - char msg[] = "connection to server failed"; - if ( search( &buf[0], bufEnd, msg, msg + strlen(msg)) != bufEnd ) - errDescription << "Licence problems."; - else - { - char msg2[] = "SEGMENTATION FAULT"; - if ( search( &buf[0], bufEnd, msg2, msg2 + strlen(msg2)) != bufEnd ) - errDescription << "ghs3d: SEGMENTATION FAULT. "; - } - } - - if ( errDescription.empty() ) - errDescription << "See " << logFile << " for problem description"; - else - errDescription << "\nSee " << logFile << " for more information"; - - return error( errDescription ); -} - -//================================================================================ -/*! - * \brief Creates _Ghs2smdsConvertor - */ -//================================================================================ - -_Ghs2smdsConvertor::_Ghs2smdsConvertor( const map & ghs2NodeMap) - :_ghs2NodeMap( & ghs2NodeMap ), _nodeByGhsId( 0 ) -{ -} - -//================================================================================ -/*! - * \brief Creates _Ghs2smdsConvertor - */ -//================================================================================ - -_Ghs2smdsConvertor::_Ghs2smdsConvertor( const vector & nodeByGhsId) - : _ghs2NodeMap( 0 ), _nodeByGhsId( &nodeByGhsId ) -{ -} - -//================================================================================ -/*! - * \brief Return SMDS element by ids of GHS3D nodes - */ -//================================================================================ - -const SMDS_MeshElement* _Ghs2smdsConvertor::getElement(const vector& ghsNodes) const -{ - size_t nbNodes = ghsNodes.size(); - vector nodes( nbNodes, 0 ); - for ( size_t i = 0; i < nbNodes; ++i ) { - int ghsNode = ghsNodes[ i ]; - if ( _ghs2NodeMap ) { - map ::const_iterator in = _ghs2NodeMap->find( ghsNode); - if ( in == _ghs2NodeMap->end() ) - return 0; - nodes[ i ] = in->second; - } - else { - if ( ghsNode < 1 || ghsNode > _nodeByGhsId->size() ) - return 0; - nodes[ i ] = (*_nodeByGhsId)[ ghsNode-1 ]; - } - } - if ( nbNodes == 1 ) - return nodes[0]; - - if ( nbNodes == 2 ) { - const SMDS_MeshElement* edge= SMDS_Mesh::FindEdge( nodes[0], nodes[1] ); - if ( !edge ) - edge = new SMDS_LinearEdge( nodes[0], nodes[1] ); - return edge; - } - if ( nbNodes == 3 ) { - const SMDS_MeshElement* face = SMDS_Mesh::FindFace( nodes ); - if ( !face ) - face = new SMDS_FaceOfNodes( nodes[0], nodes[1], nodes[2] ); - return face; - } - if ( nbNodes == 4 ) - return new SMDS_VolumeOfNodes( nodes[0], nodes[1], nodes[2], nodes[3] ); - - return 0; -} - - -//============================================================================= -/*! - * - */ -//============================================================================= -bool GHS3DPlugin_GHS3D::Evaluate(SMESH_Mesh& aMesh, - const TopoDS_Shape& aShape, - MapShapeNbElems& aResMap) -{ - int nbtri = 0, nbqua = 0; - double fullArea = 0.0; - for (TopExp_Explorer exp(aShape, TopAbs_FACE); exp.More(); exp.Next()) { - TopoDS_Face F = TopoDS::Face( exp.Current() ); - SMESH_subMesh *sm = aMesh.GetSubMesh(F); - MapShapeNbElemsItr anIt = aResMap.find(sm); - if( anIt==aResMap.end() ) { - SMESH_ComputeErrorPtr& smError = sm->GetComputeError(); - smError.reset( new SMESH_ComputeError(COMPERR_ALGO_FAILED, - "Submesh can not be evaluated",this)); - return false; - } - std::vector aVec = (*anIt).second; - nbtri += Max(aVec[SMDSEntity_Triangle],aVec[SMDSEntity_Quad_Triangle]); - nbqua += Max(aVec[SMDSEntity_Quadrangle],aVec[SMDSEntity_Quad_Quadrangle]); - GProp_GProps G; - BRepGProp::SurfaceProperties(F,G); - double anArea = G.Mass(); - fullArea += anArea; - } - - // collect info from edges - int nb0d_e = 0, nb1d_e = 0; - bool IsQuadratic = false; - bool IsFirst = true; - TopTools_MapOfShape tmpMap; - for (TopExp_Explorer exp(aShape, TopAbs_EDGE); exp.More(); exp.Next()) { - TopoDS_Edge E = TopoDS::Edge(exp.Current()); - if( tmpMap.Contains(E) ) - continue; - tmpMap.Add(E); - SMESH_subMesh *aSubMesh = aMesh.GetSubMesh(exp.Current()); - MapShapeNbElemsItr anIt = aResMap.find(aSubMesh); - std::vector aVec = (*anIt).second; - nb0d_e += aVec[SMDSEntity_Node]; - nb1d_e += Max(aVec[SMDSEntity_Edge],aVec[SMDSEntity_Quad_Edge]); - if(IsFirst) { - IsQuadratic = (aVec[SMDSEntity_Quad_Edge] > aVec[SMDSEntity_Edge]); - IsFirst = false; - } - } - tmpMap.Clear(); - - double ELen = sqrt(2.* ( fullArea/(nbtri+nbqua*2) ) / sqrt(3.0) ); - - GProp_GProps G; - BRepGProp::VolumeProperties(aShape,G); - double aVolume = G.Mass(); - double tetrVol = 0.1179*ELen*ELen*ELen; - double CoeffQuality = 0.9; - int nbVols = int(aVolume/tetrVol/CoeffQuality); - int nb1d_f = (nbtri*3 + nbqua*4 - nb1d_e) / 2; - int nb1d_in = (int) ( nbVols*6 - nb1d_e - nb1d_f ) / 5; - std::vector aVec(SMDSEntity_Last); - for(int i=SMDSEntity_Node; i -#include - -class GHS3DPlugin_Hypothesis; -class SMDS_MeshNode; -class SMESH_Mesh; -class StdMeshers_ViscousLayers; -class TCollection_AsciiString; -class _Ghs2smdsConvertor; - -class GHS3DPlugin_GHS3D: public SMESH_3D_Algo -{ -public: - GHS3DPlugin_GHS3D(int hypId, int studyId, SMESH_Gen* gen); - virtual ~GHS3DPlugin_GHS3D(); - - virtual bool CheckHypothesis(SMESH_Mesh& aMesh, - const TopoDS_Shape& aShape, - Hypothesis_Status& aStatus); - - virtual bool Compute(SMESH_Mesh& aMesh, - const TopoDS_Shape& aShape); - - virtual bool Evaluate(SMESH_Mesh& aMesh, const TopoDS_Shape& aShape, - MapShapeNbElems& aResMap); - - virtual bool Compute(SMESH_Mesh& theMesh, - SMESH_MesherHelper* aHelper); - -private: - - bool storeErrorDescription(const TCollection_AsciiString& logFile, - const _Ghs2smdsConvertor & toSmdsConvertor ); - - int _iShape; - int _nbShape; - bool _keepFiles; - const GHS3DPlugin_Hypothesis* _hyp; - const StdMeshers_ViscousLayers* _viscousLayersHyp; -}; - -/*! - * \brief Convertor of GHS3D elements to SMDS ones - */ -class _Ghs2smdsConvertor -{ - const std::map * _ghs2NodeMap; - const std::vector * _nodeByGhsId; - -public: - _Ghs2smdsConvertor( const std::map & ghs2NodeMap); - - _Ghs2smdsConvertor( const std::vector & nodeByGhsId); - - const SMDS_MeshElement* getElement(const std::vector& ghsNodes) const; -}; - -#endif diff --git a/src/GHS3DPlugin_GHS3D_i.cxx b/src/GHS3DPlugin_GHS3D_i.cxx deleted file mode 100644 index c63525a..0000000 --- a/src/GHS3DPlugin_GHS3D_i.cxx +++ /dev/null @@ -1,82 +0,0 @@ -// Copyright (C) 2004-2010 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -// SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses -// File : GHS3DPlugin_GHS3D_i.cxx -// Author : Edward AGAPOV -// Module : GHS3DPlugin -// $Header$ -// -#include "GHS3DPlugin_GHS3D_i.hxx" -#include "SMESH_Gen.hxx" -#include "GHS3DPlugin_GHS3D.hxx" - -#include "utilities.h" - -using namespace std; - -//============================================================================= -/*! - * GHS3DPlugin_GHS3D_i::GHS3DPlugin_GHS3D_i - * - * Constructor - */ -//============================================================================= - -GHS3DPlugin_GHS3D_i::GHS3DPlugin_GHS3D_i (PortableServer::POA_ptr thePOA, - int theStudyId, - ::SMESH_Gen* theGenImpl ) - : SALOME::GenericObj_i( thePOA ), - SMESH_Hypothesis_i( thePOA ), - SMESH_Algo_i( thePOA ), - SMESH_3D_Algo_i( thePOA ) -{ - MESSAGE( "GHS3DPlugin_GHS3D_i::GHS3DPlugin_GHS3D_i" ); - myBaseImpl = new ::GHS3DPlugin_GHS3D (theGenImpl->GetANewId(), - theStudyId, - theGenImpl ); -} - -//============================================================================= -/*! - * GHS3DPlugin_GHS3D_i::~GHS3DPlugin_GHS3D_i - * - * Destructor - */ -//============================================================================= - -GHS3DPlugin_GHS3D_i::~GHS3DPlugin_GHS3D_i() -{ - MESSAGE( "GHS3DPlugin_GHS3D_i::~GHS3DPlugin_GHS3D_i" ); -} - -//============================================================================= -/*! - * GHS3DPlugin_GHS3D_i::GetImpl - * - * Get implementation - */ -//============================================================================= - -::GHS3DPlugin_GHS3D* GHS3DPlugin_GHS3D_i::GetImpl() -{ - MESSAGE( "GHS3DPlugin_GHS3D_i::GetImpl" ); - return ( ::GHS3DPlugin_GHS3D* )myBaseImpl; -} - diff --git a/src/GHS3DPlugin_GHS3D_i.hxx b/src/GHS3DPlugin_GHS3D_i.hxx deleted file mode 100644 index e61fb45..0000000 --- a/src/GHS3DPlugin_GHS3D_i.hxx +++ /dev/null @@ -1,54 +0,0 @@ -// Copyright (C) 2004-2010 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -// File : GHS3DPlugin_GHS3D_i.hxx -// Author : Edward AGAPOV -// Module : GHS3DPlugin -// $Header$ -// -#ifndef _GHS3DPlugin_GHS3D_I_HXX_ -#define _GHS3DPlugin_GHS3D_I_HXX_ - -#include -#include CORBA_SERVER_HEADER(GHS3DPlugin_Algorithm) -#include CORBA_SERVER_HEADER(SALOME_Exception) - -#include "SMESH_3D_Algo_i.hxx" -#include "GHS3DPlugin_GHS3D.hxx" - -// ====================================================== -// GHS3D 3d algorithm -// ====================================================== -class GHS3DPlugin_GHS3D_i: - public virtual POA_GHS3DPlugin::GHS3DPlugin_GHS3D, - public virtual SMESH_3D_Algo_i -{ -public: - // Constructor - GHS3DPlugin_GHS3D_i (PortableServer::POA_ptr thePOA, - int theStudyId, - ::SMESH_Gen* theGenImpl ); - // Destructor - virtual ~GHS3DPlugin_GHS3D_i(); - - // Get implementation - ::GHS3DPlugin_GHS3D* GetImpl(); -}; - -#endif diff --git a/src/GHS3DPlugin_Hypothesis.cxx b/src/GHS3DPlugin_Hypothesis.cxx deleted file mode 100644 index 5079333..0000000 --- a/src/GHS3DPlugin_Hypothesis.cxx +++ /dev/null @@ -1,882 +0,0 @@ -// Copyright (C) 2004-2010 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -//============================================================================= -// File : GHS3DPlugin_Hypothesis.cxx -// Created : Wed Apr 2 12:36:29 2008 -// Author : Edward AGAPOV (eap) -//============================================================================= -// -#include "GHS3DPlugin_Hypothesis.hxx" - -#include - -#ifdef WNT -#include -#define getpid _getpid -#endif - -//======================================================================= -//function : GHS3DPlugin_Hypothesis -//======================================================================= - -GHS3DPlugin_Hypothesis::GHS3DPlugin_Hypothesis(int hypId, int studyId, SMESH_Gen * gen) - : SMESH_Hypothesis(hypId, studyId, gen), - myToMeshHoles(DefaultMeshHoles()), - myMaximumMemory(-1), - myInitialMemory(-1), - myOptimizationLevel(DefaultOptimizationLevel()), - myWorkingDirectory(DefaultWorkingDirectory()), - myKeepFiles(DefaultKeepFiles()), - myVerboseLevel(DefaultVerboseLevel()), - myToCreateNewNodes(DefaultToCreateNewNodes()), - myToUseBoundaryRecoveryVersion(DefaultToUseBoundaryRecoveryVersion()), - myToUseFemCorrection(DefaultToUseFEMCorrection()), - myToRemoveCentralPoint(DefaultToRemoveCentralPoint()), - myEnforcedVertices(DefaultEnforcedVertices()) -{ - _name = "GHS3D_Parameters"; - _param_algo_dim = 3; -} - -//======================================================================= -//function : SetToMeshHoles -//======================================================================= - -void GHS3DPlugin_Hypothesis::SetToMeshHoles(bool toMesh) -{ - if ( myToMeshHoles != toMesh ) { - myToMeshHoles = toMesh; - NotifySubMeshesHypothesisModification(); - } -} - -//======================================================================= -//function : GetToMeshHoles -//======================================================================= - -bool GHS3DPlugin_Hypothesis::GetToMeshHoles(bool checkFreeOption) const -{ - if (checkFreeOption && !myTextOption.empty()) { - if ( myTextOption.find("-c 0")) - return true; - if ( myTextOption.find("-c 1")) - return false; - } - return myToMeshHoles; -} - -//======================================================================= -//function : SetMaximumMemory -//======================================================================= - -void GHS3DPlugin_Hypothesis::SetMaximumMemory(short MB) -{ - if ( myMaximumMemory != MB ) { - myMaximumMemory = MB; - NotifySubMeshesHypothesisModification(); - } -} - -//======================================================================= -//function : GetMaximumMemory -// * automatic memory adjustment mode. Default is zero -//======================================================================= - -short GHS3DPlugin_Hypothesis::GetMaximumMemory() const -{ - return myMaximumMemory; -} - -//======================================================================= -//function : SetInitialMemory -//======================================================================= - -void GHS3DPlugin_Hypothesis::SetInitialMemory(short MB) -{ - if ( myInitialMemory != MB ) { - myInitialMemory = MB; - NotifySubMeshesHypothesisModification(); - } -} - -//======================================================================= -//function : GetInitialMemory -//======================================================================= - -short GHS3DPlugin_Hypothesis::GetInitialMemory() const -{ - return myInitialMemory; -} - -//======================================================================= -//function : SetOptimizationLevel -//======================================================================= - -void GHS3DPlugin_Hypothesis::SetOptimizationLevel(OptimizationLevel level) -{ - if ( myOptimizationLevel != level ) { - myOptimizationLevel = level; - NotifySubMeshesHypothesisModification(); - } -} - -//======================================================================= -//function : GetOptimizationLevel -//======================================================================= - -GHS3DPlugin_Hypothesis::OptimizationLevel GHS3DPlugin_Hypothesis::GetOptimizationLevel() const -{ - return (OptimizationLevel) myOptimizationLevel; -} - -//======================================================================= -//function : SetWorkingDirectory -//======================================================================= - -void GHS3DPlugin_Hypothesis::SetWorkingDirectory(const std::string& path) -{ - if ( myWorkingDirectory != path ) { - myWorkingDirectory = path; - NotifySubMeshesHypothesisModification(); - } -} - -//======================================================================= -//function : GetWorkingDirectory -//======================================================================= - -std::string GHS3DPlugin_Hypothesis::GetWorkingDirectory() const -{ - return myWorkingDirectory; -} - -//======================================================================= -//function : SetKeepFiles -//======================================================================= - -void GHS3DPlugin_Hypothesis::SetKeepFiles(bool toKeep) -{ - if ( myKeepFiles != toKeep ) { - myKeepFiles = toKeep; - NotifySubMeshesHypothesisModification(); - } -} - -//======================================================================= -//function : GetKeepFiles -//======================================================================= - -bool GHS3DPlugin_Hypothesis::GetKeepFiles() const -{ - return myKeepFiles; -} - -//======================================================================= -//function : SetVerboseLevel -//======================================================================= - -void GHS3DPlugin_Hypothesis::SetVerboseLevel(short level) -{ - if ( myVerboseLevel != level ) { - myVerboseLevel = level; - NotifySubMeshesHypothesisModification(); - } -} - -//======================================================================= -//function : GetVerboseLevel -//======================================================================= - -short GHS3DPlugin_Hypothesis::GetVerboseLevel() const -{ - return myVerboseLevel; -} - -//======================================================================= -//function : SetToCreateNewNodes -//======================================================================= - -void GHS3DPlugin_Hypothesis::SetToCreateNewNodes(bool toCreate) -{ - if ( myToCreateNewNodes != toCreate ) { - myToCreateNewNodes = toCreate; - NotifySubMeshesHypothesisModification(); - } -} - -//======================================================================= -//function : GetToCreateNewNodes -//======================================================================= - -bool GHS3DPlugin_Hypothesis::GetToCreateNewNodes() const -{ - return myToCreateNewNodes; -} - -//======================================================================= -//function : SetToUseBoundaryRecoveryVersion -//======================================================================= - -void GHS3DPlugin_Hypothesis::SetToUseBoundaryRecoveryVersion(bool toUse) -{ - if ( myToUseBoundaryRecoveryVersion != toUse ) { - myToUseBoundaryRecoveryVersion = toUse; - NotifySubMeshesHypothesisModification(); - } -} - -//======================================================================= -//function : GetToUseBoundaryRecoveryVersion -//======================================================================= - -bool GHS3DPlugin_Hypothesis::GetToUseBoundaryRecoveryVersion() const -{ - return myToUseBoundaryRecoveryVersion; -} - -//======================================================================= -//function : SetFEMCorrection -//======================================================================= - -void GHS3DPlugin_Hypothesis::SetFEMCorrection(bool toUseFem) -{ - if ( myToUseFemCorrection != toUseFem ) { - myToUseFemCorrection = toUseFem; - NotifySubMeshesHypothesisModification(); - } -} - -//======================================================================= -//function : GetFEMCorrection -//======================================================================= - -bool GHS3DPlugin_Hypothesis::GetFEMCorrection() const -{ - return myToUseFemCorrection; -} - -//======================================================================= -//function : SetToRemoveCentralPoint -//======================================================================= - -void GHS3DPlugin_Hypothesis::SetToRemoveCentralPoint(bool toRemove) -{ - if ( myToRemoveCentralPoint != toRemove ) { - myToRemoveCentralPoint = toRemove; - NotifySubMeshesHypothesisModification(); - } -} - -//======================================================================= -//function : GetToRemoveCentralPoint -//======================================================================= - -bool GHS3DPlugin_Hypothesis::GetToRemoveCentralPoint() const -{ - return myToRemoveCentralPoint; -} - -//======================================================================= -//function : SetTextOption -//======================================================================= - -void GHS3DPlugin_Hypothesis::SetTextOption(const std::string& option) -{ - if ( myTextOption != option ) { - myTextOption = option; - NotifySubMeshesHypothesisModification(); - } -} - -//======================================================================= -//function : GetTextOption -//======================================================================= - -std::string GHS3DPlugin_Hypothesis::GetTextOption() const -{ - return myTextOption; -} - -//======================================================================= -//function : SetEnforcedVertex -//======================================================================= - -void GHS3DPlugin_Hypothesis::SetEnforcedVertex(double x, double y, double z, double size) -{ - std::vector coord(3); - coord[0] = x; - coord[1] = y; - coord[2] = z; - myEnforcedVertices[coord] = size; - NotifySubMeshesHypothesisModification(); -} - -//======================================================================= -//function : GetEnforcedVertex -//======================================================================= - -double GHS3DPlugin_Hypothesis::GetEnforcedVertex(double x, double y, double z) - throw (std::invalid_argument) -{ - std::vector coord(3); - coord[0] = x; - coord[1] = y; - coord[2] = z; - if (myEnforcedVertices.count(coord)>0) - return myEnforcedVertices[coord]; - std::ostringstream msg ; - msg << "No enforced vertex at " << x << ", " << y << ", " << z; - throw std::invalid_argument(msg.str()); -} - -//======================================================================= -//function : RemoveEnforcedVertex -//======================================================================= - -void GHS3DPlugin_Hypothesis::RemoveEnforcedVertex(double x, double y, double z) - throw (std::invalid_argument) -{ - std::vector coord(3); - coord[0] = x; - coord[1] = y; - coord[2] = z; - TEnforcedVertexValues::iterator it = myEnforcedVertices.find(coord); - if (it != myEnforcedVertices.end()) { - myEnforcedVertices.erase(it); - NotifySubMeshesHypothesisModification(); - return; - } - std::ostringstream msg ; - msg << "No enforced vertex at " << x << ", " << y << ", " << z; - throw std::invalid_argument(msg.str()); -} - -//======================================================================= -//function : ClearEnforcedVertices -//======================================================================= -void GHS3DPlugin_Hypothesis::ClearEnforcedVertices() -{ - myEnforcedVertices.clear(); - NotifySubMeshesHypothesisModification(); -} - -//======================================================================= -//function : DefaultMeshHoles -//======================================================================= - -bool GHS3DPlugin_Hypothesis::DefaultMeshHoles() -{ - return false; // PAL19680 -} - -//======================================================================= -//function : DefaultMaximumMemory -//======================================================================= - -#ifndef WIN32 -#include -#else -#include -#endif - -short GHS3DPlugin_Hypothesis::DefaultMaximumMemory() -{ -#ifndef WIN32 - struct sysinfo si; - int err = sysinfo( &si ); - if ( err == 0 ) { - int ramMB = si.totalram * si.mem_unit / 1024 / 1024; - return (int) ( 0.7 * ramMB ); - } -#else - // See http://msdn.microsoft.com/en-us/library/aa366589.aspx - MEMORYSTATUSEX statex; - statex.dwLength = sizeof (statex); - int err = GlobalMemoryStatusEx (&statex); - if (err != 0) { - int totMB = - statex.ullTotalPhys / 1024 / 1024 + - statex.ullTotalPageFile / 1024 / 1024 + - statex.ullTotalVirtual / 1024 / 1024; - return (int) ( 0.7 * totMB ); - } -#endif - return 1024; -} - -//======================================================================= -//function : DefaultInitialMemory -//======================================================================= - -short GHS3DPlugin_Hypothesis::DefaultInitialMemory() -{ - return DefaultMaximumMemory(); -} - -//======================================================================= -//function : DefaultOptimizationLevel -//======================================================================= - -short GHS3DPlugin_Hypothesis::DefaultOptimizationLevel() -{ - return Medium; -} - -//======================================================================= -//function : DefaultWorkingDirectory -//======================================================================= - -std::string GHS3DPlugin_Hypothesis::DefaultWorkingDirectory() -{ - TCollection_AsciiString aTmpDir; - - char *Tmp_dir = getenv("SALOME_TMP_DIR"); - if(Tmp_dir != NULL) { - aTmpDir = Tmp_dir; - } - else { -#ifdef WIN32 - aTmpDir = TCollection_AsciiString("C:\\"); -#else - aTmpDir = TCollection_AsciiString("/tmp/"); -#endif - } - return aTmpDir.ToCString(); -} - -//======================================================================= -//function : DefaultKeepFiles -//======================================================================= - -bool GHS3DPlugin_Hypothesis::DefaultKeepFiles() -{ - return false; -} - -//======================================================================= -//function : DefaultVerboseLevel -//======================================================================= - -short GHS3DPlugin_Hypothesis::DefaultVerboseLevel() -{ - return 10; -} - -//======================================================================= -//function : DefaultToCreateNewNodes -//======================================================================= - -bool GHS3DPlugin_Hypothesis::DefaultToCreateNewNodes() -{ - return true; -} - -//======================================================================= -//function : DefaultToUseBoundaryRecoveryVersion -//======================================================================= - -bool GHS3DPlugin_Hypothesis::DefaultToUseBoundaryRecoveryVersion() -{ - return false; -} - -//======================================================================= -//function : DefaultToUseFEMCorrection -//======================================================================= - -bool GHS3DPlugin_Hypothesis::DefaultToUseFEMCorrection() -{ - return false; -} - -//======================================================================= -//function : DefaultToRemoveCentralPoint -//======================================================================= - -bool GHS3DPlugin_Hypothesis::DefaultToRemoveCentralPoint() -{ - return false; -} - -//======================================================================= -//function : DefaultEnforcedVertices -//======================================================================= - -GHS3DPlugin_Hypothesis::TEnforcedVertexValues GHS3DPlugin_Hypothesis::DefaultEnforcedVertices() -{ - return GHS3DPlugin_Hypothesis::TEnforcedVertexValues(); -} - - -//======================================================================= -//function : SaveTo -//======================================================================= - -std::ostream & GHS3DPlugin_Hypothesis::SaveTo(std::ostream & save) -{ - save << (int) myToMeshHoles << " "; - save << myMaximumMemory << " "; - save << myInitialMemory << " "; - save << myOptimizationLevel << " "; - save << myWorkingDirectory << " "; - save << (int)myKeepFiles << " "; - save << myVerboseLevel << " "; - save << (int)myToCreateNewNodes << " "; - save << (int)myToUseBoundaryRecoveryVersion << " "; - save << (int)myToUseFemCorrection << " "; - save << (int)myToRemoveCentralPoint << " "; - if (!myTextOption.empty()) { - save << "__OPTIONS_BEGIN__ "; - save << myTextOption << " "; - save << "__OPTIONS_END__ "; - } - - - TEnforcedVertexValues::iterator it = myEnforcedVertices.begin(); - if (it != myEnforcedVertices.end()) { - save << "__ENFORCED_VERTICES_BEGIN__ "; - for ( ; it != myEnforcedVertices.end(); ++it ) { - save << it->first[0] << " " - << it->first[1] << " " - << it->first[2] << " " - << it->second << " "; - } - save << "__ENFORCED_VERTICES_END__ "; - } - - return save; -} - -//======================================================================= -//function : LoadFrom -//======================================================================= - -std::istream & GHS3DPlugin_Hypothesis::LoadFrom(std::istream & load) -{ - bool isOK = true; - int i; - - isOK = (load >> i); - if (isOK) - myToMeshHoles = i; - else - load.clear(ios::badbit | load.rdstate()); - - isOK = (load >> i); - if (isOK) - myMaximumMemory = i; - else - load.clear(ios::badbit | load.rdstate()); - - isOK = (load >> i); - if (isOK) - myInitialMemory = i; - else - load.clear(ios::badbit | load.rdstate()); - - isOK = (load >> i); - if (isOK) - myOptimizationLevel = i; - else - load.clear(ios::badbit | load.rdstate()); - - isOK = (load >> myWorkingDirectory); - if (isOK) { - if ( myWorkingDirectory == "0") { // myWorkingDirectory was empty - myKeepFiles = false; - myWorkingDirectory.clear(); - } - else if ( myWorkingDirectory == "1" ) { - myKeepFiles = true; - myWorkingDirectory.clear(); - } - } - else - load.clear(ios::badbit | load.rdstate()); - - if ( !myWorkingDirectory.empty() ) { - isOK = (load >> i); - if (isOK) - myKeepFiles = i; - else - load.clear(ios::badbit | load.rdstate()); - } - - isOK = (load >> i); - if (isOK) - myVerboseLevel = (short) i; - else - load.clear(ios::badbit | load.rdstate()); - - isOK = (load >> i); - if (isOK) - myToCreateNewNodes = (bool) i; - else - load.clear(ios::badbit | load.rdstate()); - - isOK = (load >> i); - if (isOK) - myToUseBoundaryRecoveryVersion = (bool) i; - else - load.clear(ios::badbit | load.rdstate()); - - isOK = (load >> i); - if (isOK) - myToUseFemCorrection = (bool) i; - else - load.clear(ios::badbit | load.rdstate()); - - isOK = (load >> i); - if (isOK) - myToRemoveCentralPoint = (bool) i; - else - load.clear(ios::badbit | load.rdstate()); - - std::string separator; - bool hasOptions = false; - bool hasEnforcedVertices = false; - isOK = (load >> separator); - - if (isOK) - if (separator == "__OPTIONS_BEGIN__") - hasOptions = true; - else if (separator == "__ENFORCED_VERTICES_BEGIN__") - hasEnforcedVertices = true; - - if (hasOptions) { - std::string txt; - while (isOK) { - isOK = (load >> txt); - if (isOK) { - if (txt == "__OPTIONS_END__") { - if (!myTextOption.empty()) { - // Remove last space - myTextOption.erase(myTextOption.end()-1); - } - isOK = false; - break; - } - myTextOption += txt; - myTextOption += " "; - } - } - } - - if (hasOptions) { - isOK = (load >> separator); - if (isOK) - if (separator == "__ENFORCED_VERTICES_BEGIN__") - hasEnforcedVertices = true; - } - - if (hasEnforcedVertices) { - std::string txt; - double x,y,z,size; - while (isOK) { - isOK = (load >> txt); - if (isOK) { - if (txt == "__ENFORCED_VERTICES_END__") { - isOK = false; - break; - } - x = atof(txt.c_str()); - isOK = (load >> y >> z >> size); - } - if (isOK) { - std::vector coord; - coord.push_back(x); - coord.push_back(y); - coord.push_back(z); - myEnforcedVertices[ coord ] = size; - } - } - } - - return load; -} - -//======================================================================= -//function : SetParametersByMesh -//======================================================================= - -bool GHS3DPlugin_Hypothesis::SetParametersByMesh(const SMESH_Mesh* ,const TopoDS_Shape&) -{ - return false; -} - - -//================================================================================ -/*! - * \brief Return false - */ -//================================================================================ - -bool GHS3DPlugin_Hypothesis::SetParametersByDefaults(const TDefaults& /*dflts*/, - const SMESH_Mesh* /*theMesh*/) -{ - return false; -} - -//================================================================================ -/*! - * \brief Return command to run ghs3d mesher excluding file prefix (-f) - */ -//================================================================================ - -std::string GHS3DPlugin_Hypothesis::CommandToRun(const GHS3DPlugin_Hypothesis* hyp, - const bool hasShapeToMesh) -{ - TCollection_AsciiString cmd( "ghs3d" ); - // check if any option is overridden by hyp->myTextOption - bool m = hyp ? ( hyp->myTextOption.find("-m") == std::string::npos ) : true; - bool M = hyp ? ( hyp->myTextOption.find("-M") == std::string::npos ) : true; - bool c = hyp ? ( hyp->myTextOption.find("-c") == std::string::npos ) : true; - bool o = hyp ? ( hyp->myTextOption.find("-o") == std::string::npos ) : true; - bool p0 = hyp ? ( hyp->myTextOption.find("-p0") == std::string::npos ) : true; - bool C = hyp ? ( hyp->myTextOption.find("-C") == std::string::npos ) : true; - bool v = hyp ? ( hyp->myTextOption.find("-v") == std::string::npos ) : true; - bool fem = hyp ? ( hyp->myTextOption.find("-FEM")== std::string::npos ) : true; - bool rem = hyp ? ( hyp->myTextOption.find("-no_initial_central_point")== std::string::npos ) : true; - - // if use boundary recovery version, few options are allowed - bool useBndRecovery = !C; - if ( !useBndRecovery && hyp ) - useBndRecovery = hyp->myToUseBoundaryRecoveryVersion; - - // ghs3d needs 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 - if ( m ) { - short aMaximumMemory = hyp ? hyp->myMaximumMemory : -1; - cmd += " -m "; - if ( aMaximumMemory < 0 ) - cmd += DefaultMaximumMemory(); - else - cmd += aMaximumMemory; - } - if ( M && !useBndRecovery ) { - short aInitialMemory = hyp ? hyp->myInitialMemory : -1; - cmd += " -M "; - if ( aInitialMemory > 0 ) - cmd += aInitialMemory; - else - cmd += "100"; - } - // component to mesh - // 0 , all components to be meshed - // 1 , only the main ( outermost ) component to be meshed - if ( c && !useBndRecovery ) { - // We always run GHS3D with "to mesh holes'==TRUE (see PAL19680) - if ( hasShapeToMesh ) - cmd += " -c 0"; - else { - bool aToMeshHoles = hyp ? hyp->myToMeshHoles : DefaultMeshHoles(); - if ( aToMeshHoles ) - cmd += " -c 0"; - else - cmd += " -c 1"; - } - } - - // optimization level - if ( o && hyp && !useBndRecovery ) { - if ( hyp->myOptimizationLevel >= 0 && hyp->myOptimizationLevel < 5 ) { - const char* level[] = { "none" , "light" , "standard" , "standard+" , "strong" }; - cmd += " -o "; - cmd += level[ hyp->myOptimizationLevel ]; - } - } - - // to create internal nodes - if ( p0 && hyp && !hyp->myToCreateNewNodes ) { - cmd += " -p0"; - } - - // verbose mode - if ( v && hyp ) { - cmd += " -v "; - cmd += hyp->myVerboseLevel; - } - - // boundary recovery version - if ( useBndRecovery ) { - cmd += " -C"; - } - - // to use FEM correction - if ( fem && hyp && hyp->myToUseFemCorrection) { - cmd += " -FEM"; - } - - // to remove initial central point. - if ( rem && hyp && hyp->myToRemoveCentralPoint) { - cmd += " -no_initial_central_point"; - } - - // options as text - if ( hyp && !hyp->myTextOption.empty() ) { - cmd += " "; - cmd += (char*) hyp->myTextOption.c_str(); - } - -#ifdef WNT - cmd += " < NUL"; -#endif - - return cmd.ToCString(); -} - -//================================================================================ -/*! - * \brief Return a unique file name - */ -//================================================================================ - -std::string GHS3DPlugin_Hypothesis::GetFileName(const GHS3DPlugin_Hypothesis* hyp) -{ - std::string aTmpDir = hyp ? hyp->GetWorkingDirectory() : DefaultWorkingDirectory(); - const char lastChar = *aTmpDir.rbegin(); -#ifdef WIN32 - if(lastChar != '\\') aTmpDir+='\\'; -#else - if(lastChar != '/') aTmpDir+='/'; -#endif - - TCollection_AsciiString aGenericName = (char*)aTmpDir.c_str(); - aGenericName += "GHS3D_"; - aGenericName += getpid(); - aGenericName += "_"; - aGenericName += Abs((Standard_Integer)(long) aGenericName.ToCString()); - - return aGenericName.ToCString(); -} - - -//================================================================================ -/*! -* \brief Return the enforced vertices -*/ -//================================================================================ - -GHS3DPlugin_Hypothesis::TEnforcedVertexValues GHS3DPlugin_Hypothesis::GetEnforcedVertices(const GHS3DPlugin_Hypothesis* hyp) -{ - return hyp ? hyp->_GetEnforcedVertices():DefaultEnforcedVertices(); -} - diff --git a/src/GHS3DPlugin_Hypothesis.hxx b/src/GHS3DPlugin_Hypothesis.hxx deleted file mode 100644 index 28fe2bb..0000000 --- a/src/GHS3DPlugin_Hypothesis.hxx +++ /dev/null @@ -1,189 +0,0 @@ -// Copyright (C) 2004-2010 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -// GHS3DPlugin : C++ implementation -// File : GHS3DPlugin_Hypothesis.hxx -// Created : Wed Apr 2 12:21:17 2008 -// Author : Edward AGAPOV (eap) -// -#ifndef GHS3DPlugin_Hypothesis_HeaderFile -#define GHS3DPlugin_Hypothesis_HeaderFile - -#include "GHS3DPlugin_Defs.hxx" - -#include -#include - -#include -#include -#include -#include - -class GHS3DPLUGIN_EXPORT GHS3DPlugin_Hypothesis: public SMESH_Hypothesis -{ -public: - - GHS3DPlugin_Hypothesis(int hypId, int studyId, SMESH_Gen * gen); - - /*! - * To mesh "holes" in a solid or not. Default is to mesh. - */ - void SetToMeshHoles(bool toMesh); - bool GetToMeshHoles(bool checkFreeOption = false) const; - /*! - * Maximal size of memory to be used by the algorithm (in Megabytes) - */ - void SetMaximumMemory(short MB); - short GetMaximumMemory() const; - /*! - * Initial size of memory to be used by the algorithm (in Megabytes) in - * automatic memory adjustment mode. Default is zero - */ - void SetInitialMemory(short MB); - short GetInitialMemory() const; - /*! - * Optimization level: 0-none, 1-light, 2-medium, 3-standard+, 4-strong. Default is medium - */ - enum OptimizationLevel { None = 0, Light, Medium, StandardPlus, Strong }; - void SetOptimizationLevel(OptimizationLevel level); - OptimizationLevel GetOptimizationLevel() const; - /*! - * Path to working directory - */ - void SetWorkingDirectory(const std::string& path); - std::string GetWorkingDirectory() const; - /*! - * To keep working files or remove them. Log file remains in case of errors anyway. - */ - void SetKeepFiles(bool toKeep); - bool GetKeepFiles() const; - /*! - * Verbose level [0-10] - * 0 - no standard output, - * 2 - prints the data, quality statistics of the skin and final meshes and - * indicates when the final mesh is being saved. In addition the software - * gives indication regarding the CPU time. - * 10 - same as 2 plus the main steps in the computation, quality statistics - * histogram of the skin mesh, quality statistics histogram together with - * the characteristics of the final mesh. - */ - void SetVerboseLevel(short level); - short GetVerboseLevel() const; - /*! - * To create new nodes - */ - void SetToCreateNewNodes(bool toCreate); - bool GetToCreateNewNodes() const; - /*! - * To use boundary recovery version which tries to create mesh on a very poor - * quality surface mesh - */ - void SetToUseBoundaryRecoveryVersion(bool toUse); - bool GetToUseBoundaryRecoveryVersion() const; - /*! - * Applies finite-element correction by replacing overconstrained elements where - * it is possible. The process is cutting first the overconstrained edges and - * second the overconstrained facets. This insure that no edges have two boundary - * vertices and that no facets have three boundary vertices. - */ - void SetFEMCorrection(bool toUseFem); - bool GetFEMCorrection() const; - /*! - * To removes initial central point. - */ - void SetToRemoveCentralPoint(bool toRemove); - bool GetToRemoveCentralPoint() const; - /*! - * To set hiden/undocumented/advanced options - */ - void SetTextOption(const std::string& option); - std::string GetTextOption() const; - /*! - * To set an enforced vertex - */ - typedef std::map,double> TEnforcedVertexValues; - void SetEnforcedVertex(double x, double y, double z, double size); - double GetEnforcedVertex(double x, double y, double z) throw (std::invalid_argument); - void RemoveEnforcedVertex(double x, double y, double z) throw (std::invalid_argument); - const TEnforcedVertexValues _GetEnforcedVertices() const { return myEnforcedVertices; } - void ClearEnforcedVertices(); - - static bool DefaultMeshHoles(); - static short DefaultMaximumMemory(); - static short DefaultInitialMemory(); - static short DefaultOptimizationLevel(); - static std::string DefaultWorkingDirectory(); - static bool DefaultKeepFiles(); - static short DefaultVerboseLevel(); - static bool DefaultToCreateNewNodes(); - static bool DefaultToUseBoundaryRecoveryVersion(); - static bool DefaultToUseFEMCorrection(); - static bool DefaultToRemoveCentralPoint(); - static TEnforcedVertexValues DefaultEnforcedVertices(); - - /*! - * \brief Return command to run ghs3d mesher excluding file prefix (-f) - */ - static std::string CommandToRun(const GHS3DPlugin_Hypothesis* hyp, - const bool hasShapeToMesh=true); - /*! - * \brief Return a unique file name - */ - static std::string GetFileName(const GHS3DPlugin_Hypothesis* hyp); - /*! - * \brief Return the enforced vertices - */ - static TEnforcedVertexValues GetEnforcedVertices(const GHS3DPlugin_Hypothesis* hyp); - - // Persistence - virtual std::ostream & SaveTo(std::ostream & save); - virtual std::istream & LoadFrom(std::istream & load); - friend GHS3DPLUGIN_EXPORT std::ostream & operator <<(std::ostream & save, GHS3DPlugin_Hypothesis & hyp); - friend GHS3DPLUGIN_EXPORT std::istream & operator >>(std::istream & load, GHS3DPlugin_Hypothesis & hyp); - - /*! - * \brief Does nothing - */ - virtual bool SetParametersByMesh(const SMESH_Mesh* theMesh, const TopoDS_Shape& theShape); - - /*! - * \brief Does nothing - */ - virtual bool SetParametersByDefaults(const TDefaults& dflts, const SMESH_Mesh* theMesh=0); - -private: - - bool myToMeshHoles; - short myMaximumMemory; - short myInitialMemory; - short myOptimizationLevel; - bool myKeepFiles; - std::string myWorkingDirectory; - short myVerboseLevel; - bool myToCreateNewNodes; - bool myToUseBoundaryRecoveryVersion; - bool myToUseFemCorrection; - bool myToRemoveCentralPoint; - std::string myTextOption; - TEnforcedVertexValues myEnforcedVertices; - -}; - - -#endif diff --git a/src/GHS3DPlugin_Hypothesis_i.cxx b/src/GHS3DPlugin_Hypothesis_i.cxx deleted file mode 100644 index ff3953e..0000000 --- a/src/GHS3DPlugin_Hypothesis_i.cxx +++ /dev/null @@ -1,460 +0,0 @@ -// Copyright (C) 2004-2010 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -// File : GHS3DPlugin_Hypothesis_i.cxx -// Created : Wed Apr 2 13:53:01 2008 -// Author : Edward AGAPOV (eap) -// -#include "GHS3DPlugin_Hypothesis_i.hxx" - -#include -#include - -#include -#include -#include - -//======================================================================= -//function : GHS3DPlugin_Hypothesis_i -//======================================================================= - -GHS3DPlugin_Hypothesis_i::GHS3DPlugin_Hypothesis_i (PortableServer::POA_ptr thePOA, - int theStudyId, - ::SMESH_Gen* theGenImpl) - : SALOME::GenericObj_i( thePOA ), - SMESH_Hypothesis_i( thePOA ) -{ - MESSAGE( "GHS3DPlugin_Hypothesis_i::GHS3DPlugin_Hypothesis_i" ); - myBaseImpl = new ::GHS3DPlugin_Hypothesis (theGenImpl->GetANewId(), - theStudyId, - theGenImpl); -} - -//======================================================================= -//function : ~GHS3DPlugin_Hypothesis_i -//======================================================================= - -GHS3DPlugin_Hypothesis_i::~GHS3DPlugin_Hypothesis_i() -{ - MESSAGE( "GHS3DPlugin_Hypothesis_i::~GHS3DPlugin_Hypothesis_i" ); -} - -//======================================================================= -//function : SetToMeshHoles -//======================================================================= - -void GHS3DPlugin_Hypothesis_i::SetToMeshHoles(CORBA::Boolean toMesh) -{ - ASSERT(myBaseImpl); - this->GetImpl()->SetToMeshHoles(toMesh); - SMESH::TPythonDump() << _this() << ".SetToMeshHoles( " << toMesh << " )"; -} - -//======================================================================= -//function : GetToMeshHoles -//======================================================================= - -CORBA::Boolean GHS3DPlugin_Hypothesis_i::GetToMeshHoles() -{ - ASSERT(myBaseImpl); - return this->GetImpl()->GetToMeshHoles(); -} - -//======================================================================= -//function : SetMaximumMemory -//======================================================================= - -void GHS3DPlugin_Hypothesis_i::SetMaximumMemory(CORBA::Short MB) - throw ( SALOME::SALOME_Exception ) -{ - if ( MB == 0 ) - THROW_SALOME_CORBA_EXCEPTION( "Invalid memory size",SALOME::BAD_PARAM ); - ASSERT(myBaseImpl); - this->GetImpl()->SetMaximumMemory(MB); - SMESH::TPythonDump() << _this() << ".SetMaximumMemory( " << MB << " )"; -} - -//======================================================================= -//function : GetMaximumMemory -//======================================================================= - -CORBA::Short GHS3DPlugin_Hypothesis_i::GetMaximumMemory() -{ - ASSERT(myBaseImpl); - return this->GetImpl()->GetMaximumMemory(); -} - -//======================================================================= -//function : SetInitialMemory -//======================================================================= - -void GHS3DPlugin_Hypothesis_i::SetInitialMemory(CORBA::Short MB) - throw ( SALOME::SALOME_Exception ) -{ - if ( MB == 0 ) - THROW_SALOME_CORBA_EXCEPTION( "Invalid memory size",SALOME::BAD_PARAM ); - ASSERT(myBaseImpl); - this->GetImpl()->SetInitialMemory(MB); - SMESH::TPythonDump() << _this() << ".SetInitialMemory( " << MB << " )"; -} - -//======================================================================= -//function : GetInitialMemory -//======================================================================= - -CORBA::Short GHS3DPlugin_Hypothesis_i::GetInitialMemory() -{ - ASSERT(myBaseImpl); - return this->GetImpl()->GetInitialMemory(); -} - -//======================================================================= -//function : SetOptimizationLevel -//======================================================================= - -void GHS3DPlugin_Hypothesis_i::SetOptimizationLevel(CORBA::Short level) - throw ( SALOME::SALOME_Exception ) -{ - ::GHS3DPlugin_Hypothesis::OptimizationLevel l = - (::GHS3DPlugin_Hypothesis::OptimizationLevel) level; - if ( l < ::GHS3DPlugin_Hypothesis::None || - l > ::GHS3DPlugin_Hypothesis::Strong ) - THROW_SALOME_CORBA_EXCEPTION( "Invalid optimization level",SALOME::BAD_PARAM ); - - ASSERT(myBaseImpl); - this->GetImpl()->SetOptimizationLevel(l); - SMESH::TPythonDump() << _this() << ".SetOptimizationLevel( " << level << " )"; -} - -//======================================================================= -//function : GetOptimizationLevel -//======================================================================= - -CORBA::Short GHS3DPlugin_Hypothesis_i::GetOptimizationLevel() -{ - ASSERT(myBaseImpl); - return this->GetImpl()->GetOptimizationLevel(); -} - -//======================================================================= -//function : SetWorkingDirectory -//======================================================================= - -void GHS3DPlugin_Hypothesis_i::SetWorkingDirectory(const char* path) throw ( SALOME::SALOME_Exception ) -{ - if (!path ) - THROW_SALOME_CORBA_EXCEPTION( "Null working directory",SALOME::BAD_PARAM ); - - string file(path); - const char lastChar = *file.rbegin(); -#ifdef WIN32 - if ( lastChar != '\\' ) file += '\\'; -#else - if ( lastChar != '/' ) file += '/'; -#endif - file += "GHS3D.log"; - SMESH_Mesh_i::PrepareForWriting (file.c_str()); - - ASSERT(myBaseImpl); - this->GetImpl()->SetWorkingDirectory(path); - SMESH::TPythonDump() << _this() << ".SetWorkingDirectory( '" << path << "' )"; -} - -//======================================================================= -//function : GetWorkingDirectory -//======================================================================= - -char* GHS3DPlugin_Hypothesis_i::GetWorkingDirectory() -{ - ASSERT(myBaseImpl); - return CORBA::string_dup( this->GetImpl()->GetWorkingDirectory().c_str() ); -} - -//======================================================================= -//function : SetKeepFiles -//======================================================================= - -void GHS3DPlugin_Hypothesis_i::SetKeepFiles(CORBA::Boolean toKeep) -{ - ASSERT(myBaseImpl); - this->GetImpl()->SetKeepFiles(toKeep); - SMESH::TPythonDump() << _this() << ".SetKeepFiles( " << toKeep << " )"; -} - -//======================================================================= -//function : GetKeepFiles -//======================================================================= - -CORBA::Boolean GHS3DPlugin_Hypothesis_i::GetKeepFiles() -{ - ASSERT(myBaseImpl); - return this->GetImpl()->GetKeepFiles(); -} - -//======================================================================= -//function : SetVerboseLevel -//======================================================================= - -void GHS3DPlugin_Hypothesis_i::SetVerboseLevel(CORBA::Short level) - throw ( SALOME::SALOME_Exception ) -{ - if (level < 0 || level > 10 ) - THROW_SALOME_CORBA_EXCEPTION( "Invalid verbose level, valid range is [0-10]", - SALOME::BAD_PARAM ); - ASSERT(myBaseImpl); - this->GetImpl()->SetVerboseLevel(level); - SMESH::TPythonDump() << _this() << ".SetVerboseLevel( " << level << " )"; -} - -//======================================================================= -//function : GetVerboseLevel -//======================================================================= - -CORBA::Short GHS3DPlugin_Hypothesis_i::GetVerboseLevel() -{ - ASSERT(myBaseImpl); - return this->GetImpl()->GetVerboseLevel(); -} - -//======================================================================= -//function : SetToCreateNewNodes -//======================================================================= - -void GHS3DPlugin_Hypothesis_i::SetToCreateNewNodes(CORBA::Boolean toCreate) -{ - ASSERT(myBaseImpl); - this->GetImpl()->SetToCreateNewNodes(toCreate); - SMESH::TPythonDump() << _this() << ".SetToCreateNewNodes( " << toCreate << " )"; -} - -//======================================================================= -//function : GetToCreateNewNodes -//======================================================================= - -CORBA::Boolean GHS3DPlugin_Hypothesis_i::GetToCreateNewNodes() -{ - ASSERT(myBaseImpl); - return this->GetImpl()->GetToCreateNewNodes(); -} - -//======================================================================= -//function : SetToUseBoundaryRecoveryVersion -//======================================================================= - -void GHS3DPlugin_Hypothesis_i::SetToUseBoundaryRecoveryVersion(CORBA::Boolean toUse) -{ - ASSERT(myBaseImpl); - this->GetImpl()->SetToUseBoundaryRecoveryVersion(toUse); - SMESH::TPythonDump() << _this() << ".SetToUseBoundaryRecoveryVersion( " << toUse << " )"; -} - -//======================================================================= -//function : GetToUseBoundaryRecoveryVersion -//======================================================================= - -CORBA::Boolean GHS3DPlugin_Hypothesis_i::GetToUseBoundaryRecoveryVersion() -{ - ASSERT(myBaseImpl); - return this->GetImpl()->GetToUseBoundaryRecoveryVersion(); -} - -//======================================================================= -//function : SetFEMCorrection -//======================================================================= - -void GHS3DPlugin_Hypothesis_i::SetFEMCorrection(CORBA::Boolean toUseFem) -{ - ASSERT(myBaseImpl); - this->GetImpl()->SetFEMCorrection(toUseFem); - SMESH::TPythonDump() << _this() << ".SetFEMCorrection( " << toUseFem << " )"; -} - -//======================================================================= -//function : GetFEMCorrection -//======================================================================= - -CORBA::Boolean GHS3DPlugin_Hypothesis_i::GetFEMCorrection() -{ - ASSERT(myBaseImpl); - return this->GetImpl()->GetFEMCorrection(); -} - -//======================================================================= -//function : SetToRemoveCentralPoint -//======================================================================= - -void GHS3DPlugin_Hypothesis_i::SetToRemoveCentralPoint(CORBA::Boolean toRemove) -{ - ASSERT(myBaseImpl); - this->GetImpl()->SetToRemoveCentralPoint(toRemove); - SMESH::TPythonDump() << _this() << ".SetToRemoveCentralPoint( " << toRemove << " )"; -} - -//======================================================================= -//function : GetToRemoveCentralPoint -//======================================================================= - -CORBA::Boolean GHS3DPlugin_Hypothesis_i::GetToRemoveCentralPoint() -{ - ASSERT(myBaseImpl); - return this->GetImpl()->GetToRemoveCentralPoint(); -} - -//======================================================================= -//function : SetTextOption -//======================================================================= - -void GHS3DPlugin_Hypothesis_i::SetTextOption(const char* option) -{ - ASSERT(myBaseImpl); - this->GetImpl()->SetTextOption(option); - SMESH::TPythonDump() << _this() << ".SetTextOption( '" << option << "' )"; -} - -//======================================================================= -//function : GetTextOption -//======================================================================= - -char* GHS3DPlugin_Hypothesis_i::GetTextOption() -{ - ASSERT(myBaseImpl); - return CORBA::string_dup( this->GetImpl()->GetTextOption().c_str() ); -} - -//======================================================================= -//function : SetEnforcedVertex -//======================================================================= - -void GHS3DPlugin_Hypothesis_i::SetEnforcedVertex(CORBA::Double x, CORBA::Double y, CORBA::Double z, CORBA::Double size) -{ - ASSERT(myBaseImpl); - this->GetImpl()->SetEnforcedVertex(x,y,z,size); - SMESH::TPythonDump() << _this() << ".SetEnforcedVertex( " << x << ", " << y << ", " << z << ", " << size << " )"; -} - -//======================================================================= -//function : GetEnforcedVertex -//======================================================================= - -CORBA::Double GHS3DPlugin_Hypothesis_i::GetEnforcedVertex(CORBA::Double x, CORBA::Double y, CORBA::Double z) - throw (SALOME::SALOME_Exception) -{ - ASSERT(myBaseImpl); - try { - return this->GetImpl()->GetEnforcedVertex(x,y,z); - } - catch (const std::invalid_argument& ex) { - SALOME::ExceptionStruct ExDescription; - ExDescription.text = ex.what(); - ExDescription.type = SALOME::BAD_PARAM; - ExDescription.sourceFile = "GHS3DPlugin_Hypothesis::GetEnforcedVertex(x,y,z)"; - ExDescription.lineNumber = 0; - throw SALOME::SALOME_Exception(ExDescription); - } - catch (SALOME_Exception& ex) { - THROW_SALOME_CORBA_EXCEPTION( ex.what() ,SALOME::BAD_PARAM ); - } - return 0; -} - -//======================================================================= -//function : GetEnforcedVertices -//======================================================================= - -GHS3DPlugin::GHS3DEnforcedVertexList* GHS3DPlugin_Hypothesis_i::GetEnforcedVertices() -{ - ASSERT(myBaseImpl); - GHS3DPlugin::GHS3DEnforcedVertexList_var result = new GHS3DPlugin::GHS3DEnforcedVertexList(); - - const ::GHS3DPlugin_Hypothesis::TEnforcedVertexValues sizeMaps = this->GetImpl()->_GetEnforcedVertices(); - int size = sizeMaps.size(); - result->length( size ); - - ::GHS3DPlugin_Hypothesis::TEnforcedVertexValues::const_iterator it; - int i = 0; - for (it = sizeMaps.begin() ; it != sizeMaps.end(); it++ ) { - GHS3DPlugin::GHS3DEnforcedVertex_var myVertex = new GHS3DPlugin::GHS3DEnforcedVertex(); - myVertex->x = it->first[0]; - myVertex->y = it->first[1]; - myVertex->z = it->first[2]; - myVertex->size = it->second; - result[i]=myVertex; - i++; - } - - return result._retn(); -} - -//======================================================================= -//function : RemoveEnforcedVertex -//======================================================================= - -void GHS3DPlugin_Hypothesis_i::RemoveEnforcedVertex(CORBA::Double x, CORBA::Double y, CORBA::Double z) - throw (SALOME::SALOME_Exception) -{ - ASSERT(myBaseImpl); - try { - this->GetImpl()->RemoveEnforcedVertex(x,y,z); - SMESH::TPythonDump() << _this() << ".RemoveEnforcedVertex( " << x << ", " << y << ", " << z << " )"; - } - catch (const std::invalid_argument& ex) { - SALOME::ExceptionStruct ExDescription; - ExDescription.text = ex.what(); - ExDescription.type = SALOME::BAD_PARAM; - ExDescription.sourceFile = "GHS3DPlugin_Hypothesis::RemoveEnforcedVertex(x,y,z)"; - ExDescription.lineNumber = 0; - throw SALOME::SALOME_Exception(ExDescription); - } - catch (SALOME_Exception& ex) { - THROW_SALOME_CORBA_EXCEPTION( ex.what() ,SALOME::BAD_PARAM ); - } -} - -//======================================================================= -//function : ClearEnforcedVertices -//======================================================================= - -void GHS3DPlugin_Hypothesis_i::ClearEnforcedVertices() -{ - ASSERT(myBaseImpl); - this->GetImpl()->ClearEnforcedVertices(); -} - -//============================================================================= -/*! - * Get implementation - */ -//============================================================================= - -::GHS3DPlugin_Hypothesis* GHS3DPlugin_Hypothesis_i::GetImpl() -{ - return (::GHS3DPlugin_Hypothesis*)myBaseImpl; -} - -//================================================================================ -/*! - * \brief Verify whether hypothesis supports given entity type - */ -//================================================================================ - -CORBA::Boolean GHS3DPlugin_Hypothesis_i::IsDimSupported( SMESH::Dimension type ) -{ - return type == SMESH::DIM_3D; -} - diff --git a/src/GHS3DPlugin_Hypothesis_i.hxx b/src/GHS3DPlugin_Hypothesis_i.hxx deleted file mode 100644 index 0cf9a26..0000000 --- a/src/GHS3DPlugin_Hypothesis_i.hxx +++ /dev/null @@ -1,140 +0,0 @@ -// Copyright (C) 2004-2010 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -// GHS3DPlugin : C++ implementation -// File : GHS3DPlugin_Hypothesis_i.hxx -// Date : 03/04/2006 -// Project : SALOME -// -#ifndef _GHS3DPlugin_Hypothesis_i_HXX_ -#define _GHS3DPlugin_Hypothesis_i_HXX_ - -#include "GHS3DPlugin_Defs.hxx" - -#include -#include CORBA_SERVER_HEADER(GHS3DPlugin_Algorithm) - -#include "SMESH_Hypothesis_i.hxx" -#include "GHS3DPlugin_Hypothesis.hxx" - -class SMESH_Gen; - -// GHS3DPlugin parameters hypothesis - -class GHS3DPLUGIN_EXPORT GHS3DPlugin_Hypothesis_i: - public virtual POA_GHS3DPlugin::GHS3DPlugin_Hypothesis, - public virtual SMESH_Hypothesis_i -{ - public: - // Constructor - GHS3DPlugin_Hypothesis_i (PortableServer::POA_ptr thePOA, - int theStudyId, - ::SMESH_Gen* theGenImpl); - // Destructor - virtual ~GHS3DPlugin_Hypothesis_i(); - - /*! - * To mesh "holes" in a solid or not. Default is to mesh. - */ - void SetToMeshHoles(CORBA::Boolean toMesh); - CORBA::Boolean GetToMeshHoles(); - /*! - * Maximal size of memory to be used by the algorithm (in Megabytes) - */ - void SetMaximumMemory(CORBA::Short MB) throw ( SALOME::SALOME_Exception ); - CORBA::Short GetMaximumMemory(); - /*! - * Initial size of memory to be used by the algorithm (in Megabytes) in - * automatic memory adjustment mode. Default is zero - */ - void SetInitialMemory(CORBA::Short MB) throw ( SALOME::SALOME_Exception ); - CORBA::Short GetInitialMemory(); - /*! - * Optimization level: 0-none, 1-light, 2-medium, 3-strong. Default is medium - */ - void SetOptimizationLevel(CORBA::Short level) throw ( SALOME::SALOME_Exception ); - CORBA::Short GetOptimizationLevel(); - /*! - * Path to working directory - */ - void SetWorkingDirectory(const char* path) throw ( SALOME::SALOME_Exception ); - char* GetWorkingDirectory(); - /*! - * To keep working files or remove them. Log file remains in case of errors anyway. - */ - void SetKeepFiles(CORBA::Boolean toKeep); - CORBA::Boolean GetKeepFiles(); - /*! - * Verbose level [0-10] - * 0 - no standard output, - * 2 - prints the data, quality statistics of the skin and final meshes and - * indicates when the final mesh is being saved. In addition the software - * gives indication regarding the CPU time. - * 10 - same as 2 plus the main steps in the computation, quality statistics - * histogram of the skin mesh, quality statistics histogram together with - * the characteristics of the final mesh. - */ - void SetVerboseLevel(CORBA::Short level) throw ( SALOME::SALOME_Exception ); - CORBA::Short GetVerboseLevel(); - /*! - * To create new nodes - */ - void SetToCreateNewNodes(CORBA::Boolean toCreate); - CORBA::Boolean GetToCreateNewNodes(); - /*! - * To use boundary recovery version which tries to create mesh on a very poor - * quality surface mesh - */ - void SetToUseBoundaryRecoveryVersion(CORBA::Boolean toUse); - CORBA::Boolean GetToUseBoundaryRecoveryVersion(); - /*! - * Applies finite-element correction by replacing overconstrained elements where - * it is possible. The process is cutting first the overconstrained edges and - * second the overconstrained facets. This insure that no edges have two boundary - * vertices and that no facets have three boundary vertices. - */ - void SetFEMCorrection(CORBA::Boolean toUseFem); - CORBA::Boolean GetFEMCorrection(); - /*! - * To removes initial central point. - */ - void SetToRemoveCentralPoint(CORBA::Boolean toRemove); - CORBA::Boolean GetToRemoveCentralPoint(); - /*! - * To set hiden/undocumented/advanced options - */ - void SetTextOption(const char* option); - char* GetTextOption(); - /*! - * To set an enforced vertex - */ - void SetEnforcedVertex(CORBA::Double x, CORBA::Double y, CORBA::Double z, CORBA::Double size); - CORBA::Double GetEnforcedVertex(CORBA::Double x, CORBA::Double y, CORBA::Double z) throw (SALOME::SALOME_Exception); - void RemoveEnforcedVertex(CORBA::Double x, CORBA::Double y, CORBA::Double z) throw (SALOME::SALOME_Exception); - GHS3DPlugin::GHS3DEnforcedVertexList* GetEnforcedVertices(); - void ClearEnforcedVertices(); - - // Get implementation - ::GHS3DPlugin_Hypothesis* GetImpl(); - - // Verify whether hypothesis supports given entity type - CORBA::Boolean IsDimSupported( SMESH::Dimension type ); -}; - -#endif diff --git a/src/GHS3DPlugin_i.cxx b/src/GHS3DPlugin_i.cxx deleted file mode 100644 index 0739dea..0000000 --- a/src/GHS3DPlugin_i.cxx +++ /dev/null @@ -1,68 +0,0 @@ -// Copyright (C) 2004-2010 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -// SMESH GHS3DPlugin : implementaion of SMESH idl descriptions -// File : GHS3DPlugin.cxx -// Author : Julia DOROVSKIKH -// Module : SMESH -// $Header$ -// -#include "SMESH_Hypothesis_i.hxx" - -#include "utilities.h" - -#include "GHS3DPlugin_GHS3D_i.hxx" -#include "GHS3DPlugin_Hypothesis_i.hxx" - -using namespace std; - -template class GHS3DPlugin_Creator_i:public HypothesisCreator_i -{ - // as we have 'module GHS3DPlugin' in GHS3DPlugin_Algorithm.idl - virtual std::string GetModuleName() { return "GHS3DPlugin"; } -}; - -//============================================================================= -/*! - * - */ -//============================================================================= - -extern "C" -{ - GHS3DPLUGIN_EXPORT - GenericHypothesisCreator_i* GetHypothesisCreator (const char* aHypName) - { - MESSAGE("GetHypothesisCreator " << aHypName); - - GenericHypothesisCreator_i* aCreator = 0; - - // Hypotheses - - // Algorithm - if (strcmp(aHypName, "GHS3D_3D") == 0) - aCreator = new GHS3DPlugin_Creator_i; - // Hypothesis - else if (strcmp(aHypName, "GHS3D_Parameters") == 0) - aCreator = new GHS3DPlugin_Creator_i; - else ; - - return aCreator; - } -} diff --git a/src/Makefile.am b/src/Makefile.am index 8130764..a6d0a7a 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -25,45 +25,10 @@ # include $(top_srcdir)/adm_local/unix/make_common_starter.am +SUBDIRS = GHS3DPlugin + if GHS3DPLUGIN_ENABLE_GUI - SUBDIRS = GUI + SUBDIRS += GUI endif -DIST_SUBDIRS = GUI - -# header files -salomeinclude_HEADERS = \ - GHS3DPlugin_Defs.hxx \ - GHS3DPlugin_GHS3D.hxx \ - GHS3DPlugin_GHS3D_i.hxx \ - GHS3DPlugin_Hypothesis.hxx \ - GHS3DPlugin_Hypothesis_i.hxx - -# Libraries targets -lib_LTLIBRARIES = libGHS3DEngine.la - -dist_libGHS3DEngine_la_SOURCES = \ - GHS3DPlugin_GHS3D.cxx \ - GHS3DPlugin_GHS3D_i.cxx \ - GHS3DPlugin_i.cxx \ - GHS3DPlugin_Hypothesis.cxx \ - GHS3DPlugin_Hypothesis_i.cxx - -libGHS3DEngine_la_CPPFLAGS = \ - $(KERNEL_CXXFLAGS) \ - $(CAS_CPPFLAGS) \ - $(GEOM_CXXFLAGS) \ - $(MED_CXXFLAGS) \ - $(SMESH_CXXFLAGS) \ - $(VTK_INCLUDES) \ - $(BOOST_CPPFLAGS) \ - $(CORBA_CXXFLAGS) \ - $(CORBA_INCLUDES) \ - -I$(top_builddir)/idl - -libGHS3DEngine_la_LDFLAGS = \ - ../idl/libSalomeIDLGHS3DPLUGIN.la \ - $(CAS_KERNEL) -lTKBRep -lTKG2d -lTKG3d -lTKTopAlgo -lTKGeomBase -lTKGeomAlgo \ - $(MED_LDFLAGS) -lSalomeIDLMED \ - $(SMESH_LDFLAGS) -lSMESHimpl -lSMESHEngine -lSMESHDS -lSMDS -lStdMeshers \ - $(KERNEL_LDFLAGS) -lSalomeGenericObj -lSALOMELocalTrace -lSALOMEBasics +DIST_SUBDIRS = GHS3DPlugin GUI