From: vsr Date: Tue, 29 Jul 2008 05:52:47 +0000 (+0000) Subject: Merge from V4_1_0_maintainance branch (from tag mergeto_BR_QT4_Dev_08Jul08) X-Git-Tag: V5_1_0a1~2 X-Git-Url: http://git.salome-platform.org/gitweb/?a=commitdiff_plain;h=3cfa2cf1a0c34bb553fc8bd6cc4f678629ecbd6f;p=plugins%2Fhybridplugin.git Merge from V4_1_0_maintainance branch (from tag mergeto_BR_QT4_Dev_08Jul08) --- diff --git a/build_configure b/build_configure index 5c6eb44..c9424ed 100755 --- a/build_configure +++ b/build_configure @@ -11,6 +11,19 @@ ORIG_DIR=`pwd` CONF_DIR=`echo $0 | sed -e "s,[^/]*$,,;s,/$,,;s,^$,.,"` +GHS3DPLUGIN_WITH_GUI="yes" + +for option +do + case $option in + -with-gui | --with-gui) + GHS3DPLUGIN_WITH_GUI="yes" + break;; + -without-gui | --without-gui | -with-gui=no | --with-gui=no) + GHS3DPLUGIN_WITH_GUI="no" + break;; + esac +done ######################################################################## # Test if the KERNEL_ROOT_DIR is set correctly @@ -43,6 +56,14 @@ if test ! -d "${GEOM_ROOT_DIR}"; then exit fi +######################################################################## +# Test if the MED_ROOT_DIR is set correctly + +if test ! -d "${MED_ROOT_DIR}"; then + echo "failed : MED_ROOT_DIR variable is not correct !" + exit +fi + ######################################################################## # Test if the SMESH_ROOT_DIR is set correctly @@ -54,6 +75,11 @@ fi cd ${CONF_DIR} ABS_CONF_DIR=`pwd` +####################################################################### +# Update configure.ac script: to set GHS3DPLUGIN_WITH_GUI variable +sed -e s/GHS3DPLUGIN_WITH_GUI=[a-z]*/GHS3DPLUGIN_WITH_GUI=${GHS3DPLUGIN_WITH_GUI}/g configure.ac > configure.tmp +mv -f configure.tmp configure.ac + mkdir -p salome_adm/unix/config_files #cp -f ${KERNEL_ROOT_DIR}/salome_adm/unix/config_files/* salome_adm/unix/config_files #cp -f ${KERNEL_ROOT_DIR}/salome_adm/unix/pythonbe.py salome_adm/unix @@ -82,11 +108,20 @@ cp -f ${KERNEL_ROOT_DIR}/salome_adm/unix/SALOMEconfig.h.in salome_adm/unix # autom4te.cache (directory) echo "====================================================== aclocal" -aclocal -I adm_local/unix/config_files \ - -I ${KERNEL_ROOT_DIR}/salome_adm/unix/config_files \ - -I ${GUI_ROOT_DIR}/adm_local/unix/config_files \ - -I ${GEOM_ROOT_DIR}/adm_local/unix/config_files \ - -I ${SMESH_ROOT_DIR}/adm_local/unix/config_files || exit 1 +if test ${GHS3DPLUGIN_WITH_GUI} = yes; then + aclocal -I adm_local/unix/config_files \ + -I ${KERNEL_ROOT_DIR}/salome_adm/unix/config_files \ + -I ${GUI_ROOT_DIR}/adm_local/unix/config_files \ + -I ${MED_ROOT_DIR}/adm_local/unix/config_files \ + -I ${GEOM_ROOT_DIR}/adm_local/unix/config_files \ + -I ${SMESH_ROOT_DIR}/adm_local/unix/config_files || exit 1 +else + aclocal -I adm_local/unix/config_files \ + -I ${KERNEL_ROOT_DIR}/salome_adm/unix/config_files \ + -I ${MED_ROOT_DIR}/adm_local/unix/config_files \ + -I ${GEOM_ROOT_DIR}/adm_local/unix/config_files \ + -I ${SMESH_ROOT_DIR}/adm_local/unix/config_files || exit 1 +fi # ____________________________________________________________________ # libtoolize creates some configuration files (ltmain.sh, diff --git a/configure.ac b/configure.ac index 37a3d7b..677aede 100644 --- a/configure.ac +++ b/configure.ac @@ -206,44 +206,65 @@ AC_SUBST_FILE(CORBA) corba=make_$ORB CORBA=adm_local/unix/$corba -echo -echo --------------------------------------------- -echo testing openGL -echo --------------------------------------------- -echo +GHS3DPLUGIN_WITH_GUI=yes -CHECK_OPENGL +AM_CONDITIONAL(GHS3DPLUGIN_ENABLE_GUI, [test "${GHS3DPLUGIN_WITH_GUI}" = "yes"]) -echo -echo --------------------------------------------- -echo testing QT -echo --------------------------------------------- -echo +if test "${GHS3DPLUGIN_WITH_GUI}" = "yes"; then -CHECK_QT + echo + echo --------------------------------------------- + echo testing openGL + echo --------------------------------------------- + echo -echo -echo --------------------------------------------- -echo testing VTK -echo --------------------------------------------- -echo + CHECK_OPENGL -CHECK_VTK + echo + echo --------------------------------------------- + echo testing QT + echo --------------------------------------------- + echo -echo -echo --------------------------------------------- -echo testing HDF5 -echo --------------------------------------------- -echo + CHECK_QT -CHECK_HDF5 + echo + echo --------------------------------------------- + echo testing VTK + echo --------------------------------------------- + echo + + CHECK_VTK + + echo + echo --------------------------------------------- + echo Testing GUI + echo --------------------------------------------- + echo + + CHECK_SALOME_GUI + + echo + echo --------------------------------------------- + echo Testing full GUI + echo --------------------------------------------- + echo + + CHECK_CORBA_IN_GUI + if test "x${CORBA_IN_GUI}" != "xyes"; then + echo "failed : For configure GHS3DPLUGIN module necessary full GUI !" + exit + fi +fi echo echo --------------------------------------------- -echo Testing OpenCascade +echo Testing HDF5 echo --------------------------------------------- echo +CHECK_HDF5 + echo echo --------------------------------------------- echo BOOST Library @@ -252,68 +273,46 @@ echo CHECK_BOOST -CHECK_CAS - echo echo --------------------------------------------- -echo Testing html generators +echo Testing OpenCascade echo --------------------------------------------- echo -CHECK_HTML_GENERATORS +CHECK_CAS echo echo --------------------------------------------- -echo Testing GUI +echo Testing html generators echo --------------------------------------------- echo -CHECK_SALOME_GUI +CHECK_HTML_GENERATORS echo echo --------------------------------------------- -echo Testing full GUI +echo Testing Kernel echo --------------------------------------------- echo -CHECK_CORBA_IN_GUI -if test "x${CORBA_IN_GUI}" != "xyes"; then - echo "failed : For configure CALCULATOR module necessary full GUI !" - exit -fi +CHECK_KERNEL echo echo --------------------------------------------- -echo Testing Kernel +echo Testing Geom echo --------------------------------------------- echo -CHECK_KERNEL +CHECK_GEOM echo echo --------------------------------------------- -echo Testing Geom +echo Testing Med echo --------------------------------------------- echo -CHECK_GEOM +CHECK_MED -# echo -# echo --------------------------------------------- -# echo Testing Med -# echo --------------------------------------------- -# echo -# -# CHECK_MED -# -# echo -# echo --------------------------------------------- -# echo Testing Netgen -# echo --------------------------------------------- -# echo -# -# CHECK_NETGEN -# echo echo --------------------------------------------- echo Testing SMesh @@ -337,7 +336,12 @@ echo --------------------------------------------- echo echo Configure -variables="cc_ok boost_ok threads_ok omniORB_ok occ_ok doxygen_ok Kernel_ok Geom_ok SMesh_ok GHS3D_ok" +if test "${GHS3DPLUGIN_WITH_GUI}" = "yes"; then +variables="cc_ok boost_ok threads_ok omniORB_ok occ_ok doxygen_ok Kernel_ok Geom_ok Med_ok SMesh_ok GHS3D_ok OpenGL_ok qt_ok vtk_ok" +fi +if test "${GHS3DPLUGIN_WITH_GUI}" = "no"; then +variables="cc_ok boost_ok threads_ok omniORB_ok occ_ok doxygen_ok Kernel_ok Geom_ok Med_ok SMesh_ok GHS3D_ok" +fi for var in $variables do printf " %10s : " `echo \$var | sed -e "s,_ok,,"` @@ -378,6 +382,7 @@ AC_OUTPUT([ \ ./bin/Makefile \ ./GHS3DPLUGIN_version.h \ ./src/Makefile \ + ./src/GUI/Makefile \ ./resources/Makefile \ ./idl/Makefile \ Makefile \ diff --git a/idl/GHS3DPlugin_Algorithm.idl b/idl/GHS3DPlugin_Algorithm.idl index f698e9f..983d7d8 100644 --- a/idl/GHS3DPlugin_Algorithm.idl +++ b/idl/GHS3DPlugin_Algorithm.idl @@ -26,6 +26,7 @@ #ifndef _GHS3D_Algorithm_IDL_ #define _GHS3D_Algorithm_IDL_ +#include "SALOME_Exception.idl" #include "SMESH_Hypothesis.idl" /*! @@ -40,6 +41,73 @@ module GHS3DPlugin { }; + /*! + * Parameters of "Tetrahedron (GHS3D)" algorithm + */ + interface GHS3DPlugin_Hypothesis : SMESH::SMESH_Hypothesis + { + /*! + * To mesh "holes" in a solid or not. Default is to mesh. + */ + void SetToMeshHoles(in boolean toMesh); + boolean GetToMeshHoles(); + /*! + * Maximal size of memory to be used by the algorithm (in Megabytes). + * Negative value means not to use this option + */ + void SetMaximumMemory(in short MB) raises (SALOME::SALOME_Exception); + short GetMaximumMemory(); + /*! + * Initial size of memory to be used by the algorithm (in Megabytes) in + * automatic memory adjustment mode. Default is zero. + * Negative value means not to use this option + */ + void SetInitialMemory(in short MB) raises (SALOME::SALOME_Exception); + short GetInitialMemory(); + /*! + * Optimization level: 0-none, 1-light, 2-medium, 3-strong. Default is medium + */ + void SetOptimizationLevel(in short level) raises (SALOME::SALOME_Exception); + short GetOptimizationLevel(); + /*! + * Path to working directory + */ + void SetWorkingDirectory(in string path) raises (SALOME::SALOME_Exception); + string GetWorkingDirectory(); + /*! + * To keep working files or remove them. Log file remains in case of errors anyway. + */ + void SetKeepFiles(in boolean toKeep); + 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(in short level); + short GetVerboseLevel(); + /*! + * To create new nodes + */ + void SetToCreateNewNodes(in boolean toCreate); + boolean GetToCreateNewNodes(); + /*! + * To use boundary recovery version which tries to create mesh on a very poor + * quality surface mesh + */ + void SetToUseBoundaryRecoveryVersion(in boolean toUse); + boolean GetToUseBoundaryRecoveryVersion(); + /*! + * To set hiden/undocumented/advanced options + */ + void SetTextOption(in string option); + string GetTextOption(); + }; }; #endif diff --git a/resources/GHS3DPlugin.xml b/resources/GHS3DPlugin.xml index 16ea42c..36d329a 100644 --- a/resources/GHS3DPlugin.xml +++ b/resources/GHS3DPlugin.xml @@ -7,14 +7,21 @@ + server-lib="GHS3DEngine" + gui-lib="GHS3DPluginGUI"> + + + diff --git a/resources/Makefile.am b/resources/Makefile.am index 82f19e6..f990b2c 100644 --- a/resources/Makefile.am +++ b/resources/Makefile.am @@ -28,4 +28,6 @@ include $(top_srcdir)/adm_local/unix/make_common_starter.am dist_salomeres_DATA = \ - GHS3DPlugin.xml + GHS3DPlugin.xml \ + mesh_hypo_ghs3d.png \ + mesh_tree_hypo_ghs3d.png diff --git a/resources/mesh_hypo_ghs3d.png b/resources/mesh_hypo_ghs3d.png new file mode 100644 index 0000000..3fb67d5 Binary files /dev/null and b/resources/mesh_hypo_ghs3d.png differ diff --git a/resources/mesh_tree_hypo_ghs3d.png b/resources/mesh_tree_hypo_ghs3d.png new file mode 100644 index 0000000..ad5e9f3 Binary files /dev/null and b/resources/mesh_tree_hypo_ghs3d.png differ diff --git a/src/GHS3DPlugin_Defs.hxx b/src/GHS3DPlugin_Defs.hxx new file mode 100644 index 0000000..7fee9d2 --- /dev/null +++ b/src/GHS3DPlugin_Defs.hxx @@ -0,0 +1,37 @@ +// Copyright (C) 2005 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS, L3S, LJLL, MENSI +// +// 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 + #ifdef GHS3DPLUGIN_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 index 866c3fc..e41fd38 100644 --- a/src/GHS3DPlugin_GHS3D.cxx +++ b/src/GHS3DPlugin_GHS3D.cxx @@ -24,20 +24,43 @@ // Copyright : CEA 2003 // $Header$ //============================================================================= + using namespace std; #include "GHS3DPlugin_GHS3D.hxx" +#include "GHS3DPlugin_Hypothesis.hxx" + #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 "utilities.h" @@ -47,14 +70,6 @@ using namespace std; //#include -#include -#include -#include -#include -#include -#include -#include -#include #define castToNode(n) static_cast( n ); @@ -75,6 +90,8 @@ extern "C" #include } +#define HOLE_ID -1 + //============================================================================= /*! * @@ -90,6 +107,8 @@ GHS3DPlugin_GHS3D::GHS3DPlugin_GHS3D(int hypId, int studyId, SMESH_Gen* gen) _onlyUnaryInput = false; // Compute() will be called on a compound of solids _iShape=0; _nbShape=0; + _compatibleHypothesis.push_back("GHS3D_Parameters"); + _requireShape = false; // can work without shape } //============================================================================= @@ -109,12 +128,21 @@ GHS3DPlugin_GHS3D::~GHS3DPlugin_GHS3D() */ //============================================================================= -bool GHS3DPlugin_GHS3D::CheckHypothesis ( SMESH_Mesh& aMesh, - const TopoDS_Shape& aShape, - SMESH_Hypothesis::Hypothesis_Status& aStatus ) +bool GHS3DPlugin_GHS3D::CheckHypothesis ( SMESH_Mesh& aMesh, + const TopoDS_Shape& aShape, + Hypothesis_Status& aStatus ) { -// MESSAGE("GHS3DPlugin_GHS3D::CheckHypothesis"); aStatus = SMESH_Hypothesis::HYP_OK; + + // there is only one compatible Hypothesis so far + _hyp = 0; + _keepFiles = false; + const list & hyps = GetUsedHypothesis(aMesh, aShape); + if ( !hyps.empty() ) + _hyp = static_cast ( hyps.front() ); + if ( _hyp ) + _keepFiles = _hyp->GetKeepFiles(); + return true; } @@ -127,30 +155,26 @@ static TopoDS_Shape findShape(const SMDS_MeshNode *aNode[], TopoDS_Shape aShape, const TopoDS_Shape shape[], double** box, - const int nShape) { - double *pntCoor; - int iShape, nbNode = 4; - - pntCoor = new double[3]; - for ( int i=0; i<3; i++ ) { - pntCoor[i] = 0; - for ( int j=0; jX(); - if ( i == 1) pntCoor[i] += aNode[j]->Y(); - if ( i == 2) pntCoor[i] += aNode[j]->Z(); - } - pntCoor[i] /= nbNode; - } + 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() ); + aPnt /= nbNode; - gp_Pnt aPnt(pntCoor[0], pntCoor[1], pntCoor[2]); BRepClass3d_SolidClassifier SC (aShape, aPnt, Precision::Confusion()); - if ( not(SC.State() == TopAbs_IN) ) { + 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 ( not( pntCoor[0] < box[iShape][0] || box[iShape][1] < pntCoor[0] || - pntCoor[1] < box[iShape][2] || box[iShape][3] < pntCoor[1] || - pntCoor[2] < box[iShape][4] || box[iShape][5] < pntCoor[2]) ) { + 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; } @@ -176,15 +200,6 @@ static char* readMapIntLine(char* ptr, int tab[]) { return ptr; } -//======================================================================= -//function : readLine -//purpose : -//======================================================================= - -#define GHS3DPlugin_BUFLENGTH 256 -#define GHS3DPlugin_ReadLine(aPtr,aBuf,aFile,aLineNb) \ -{ aPtr = fgets( aBuf, GHS3DPlugin_BUFLENGTH - 2, aFile ); aLineNb++; DUMP(endl); } - //======================================================================= //function : countShape //purpose : @@ -246,16 +261,17 @@ static bool writeFaces (ofstream & theFile, break; } } - if ( not idFound ) { + if ( ! idFound ) { tabID[i] = shapeID; tabShape[i] = aShape; } } for ( int i =0; i < nbShape; i++ ) { - if ( not (tabID[i] == 0) ) { + if ( tabID[i] != 0 ) { aShape = tabShape[i]; shapeID = tabID[i]; theSubMesh = theMesh->MeshElements( aShape ); + if ( !theSubMesh ) continue; itOnSubMesh = theSubMesh->GetElements(); while ( itOnSubMesh->more() ) { aFace = itOnSubMesh->next(); @@ -411,8 +427,8 @@ static bool writePoints (ofstream & theFile, while ( it->more() ) { node = it->next(); - theSmdsToGhs3dIdMap.insert( map ::value_type( node->GetID(), aGhs3dID )); - theGhs3dIdToNodeMap.insert (map ::value_type( aGhs3dID, node )); + theSmdsToGhs3dIdMap.insert( make_pair( node->GetID(), aGhs3dID )); + theGhs3dIdToNodeMap.insert( make_pair( aGhs3dID, node )); aGhs3dID++; // X Y Z DUMMY_INT @@ -478,18 +494,133 @@ static bool writePoints (ofstream & theFile, return true; } +//======================================================================= +//function : findShapeID +//purpose : find the solid corresponding to GHS3D sub-domain following +// the technique proposed in GHS3D manual in chapter +// "B.4 Subdomain (sub-region) assignment" +//======================================================================= + +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 th enodes belong to + const SMDS_MeshElement * face = meshDS->FindFace(node1,node2,node3); + if ( !face ) + return invalidID; + + // geom face the face assigned to + SMESH_MeshEditor editor(&mesh); + int geomFaceID = editor.FindShape( face ); + if ( !geomFaceID ) + return 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 )) ) + return meshDS->ShapeToIndex( solid1 ); // - no + } + + // 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 + + // find UV of node1 on geomFace + SMESH_MesherHelper helper( mesh ); + gp_XY uv = helper.GetNodeUV( geomFace, node1 ); + + // check that uv is correct + gp_Pnt node1Pnt ( node1->X(), node1->Y(), node1->Z() ); + double tol = BRep_Tool::Tolerance( geomFace ); + BRepAdaptor_Surface surface( geomFace ); + if ( node1Pnt.Distance( surface.Value( uv.X(), uv.Y() )) > 2 * tol ) { + // project node1 onto geomFace to get right UV + GeomAPI_ProjectPointOnSurf projector( node1Pnt, surface.Surface().Surface() ); + if ( !projector.IsDone() || projector.NbPoints() < 1 ) + return invalidID; + Quantity_Parameter U,V; + projector.LowerDistanceParameters(U,V); + uv = gp_XY( U,V ); + } + // normale to face at node1 + 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; + + // normale to geomFace at UV + gp_Vec du, dv; + surface.D1( uv.X(), uv.Y(), node1Pnt, du, dv ); + gp_Vec geomNormal = du ^ dv; + if ( geomNormal.SquareMagnitude() < DBL_MIN ) + return findShapeID( mesh, node2, node3, node1, toMeshHoles ); + if ( geomFace.Orientation() == TopAbs_REVERSED ) + geomNormal.Reverse(); + + // 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, - SMESHDS_Mesh* theMeshDS, + SMESH_Mesh& theMesh, TopoDS_Shape tabShape[], double** tabBox, const int nbShape, - map & theGhs3dIdToNodeMap) { - + map & theGhs3dIdToNodeMap, + bool toMeshHoles) +{ struct stat status; size_t length; @@ -497,20 +628,23 @@ static bool readResultFile(const int fileOpen, char *tetraPtr; char *shapePtr; + SMESHDS_Mesh* theMeshDS = theMesh.GetMeshDS(); + int fileStat; int nbElems, nbNodes, nbInputNodes; - int nodeId, triangleId; + int nodeId/*, triangleId*/; int nbTriangle; int ID, shapeID, ghs3dShapeID; int IdShapeRef = 1; - int compoundID = theMeshDS->ShapeToIndex( theMeshDS->ShapeToMesh() ); + 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]; + //tabID = new int[nbShape]; nodeID = new int[4]; coord = new double[3]; node = new const SMDS_MeshNode*[4]; @@ -519,9 +653,9 @@ static bool readResultFile(const int fileOpen, SMDS_MeshNode * aNewNode; map ::iterator itOnNode; SMDS_MeshElement* aTet; - - for (int i=0; i shapeIDs; +#endif // Read the file state fileStat = fstat(fileOpen, &status); @@ -540,30 +674,57 @@ static bool readResultFile(const int fileOpen, 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); // Reading the nodeCoor and update the nodeMap - for (int iNode=0; iNode < nbNodes; iNode++) { + for (int iNode=1; iNode <= nbNodes; iNode++) { for (int iCoor=0; iCoor < 3; iCoor++) coord[ iCoor ] = strtod(ptr, &ptr); - nodeAssigne[ iNode+1 ] = 1; - if ( (iNode+1) > nbInputNodes ) { - nodeAssigne[ iNode+1 ] = 0; + nodeAssigne[ iNode ] = 1; + if ( iNode > nbInputNodes ) { + nodeAssigne[ iNode ] = 0; aNewNode = theMeshDS->AddNode( coord[0],coord[1],coord[2] ); - theGhs3dIdToNodeMap.insert(make_pair( (iNode+1), aNewNode )); + theGhs3dIdToNodeMap.insert(theGhs3dIdToNodeMap.end(), make_pair( iNode, aNewNode )); } } - // Reading the number of triangles which corresponds to the number of shapes + // Reading the number of triangles which corresponds to the number of sub-domains nbTriangle = strtol(ptr, &ptr, 10); - for (int i=0; i < 3*nbShape; i++) - triangleId = 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 ); +#ifdef _DEBUG_ + cout << i+1 << " subdomain: findShapeID() returns " << tabID[i] << endl; +#endif + } catch ( Standard_Failure ) { + } catch (...) {} + } + } 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++) { @@ -573,28 +734,70 @@ static bool readResultFile(const int fileOpen, node[ iNode ] = itOnNode->second; nodeID[ iNode ] = ID; } - aTet = theMeshDS->AddVolume( node[1], node[0], node[2], node[3] ); - if ( nbShape > 1 ) { + // 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 ) { - if (iElem == 0) - aSolid = tabShape[0]; - aSolid = findShape(node, aSolid, tabShape, tabBox, nbShape); - shapeID = theMeshDS->ShapeToIndex( aSolid ); + 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 ]; } - // set new nodes and tetrahedron on to the shape + 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]->GetPosition()->GetShapeId() > 1 ) + { + shapeID = node[i]->GetPosition()->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 ) - theMeshDS->SetNodeInVolume( node[i], shapeID ); + 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 ); } - theMeshDS->SetMeshElementOnShape( aTet, shapeID ); - if ( (iElem + 1) == nbElems ) - cout << nbElems << " tetrahedrons have been associated to " << nbShape << " shapes" << endl; } + + if ( nbElems ) + cout << nbElems << " tetrahedrons have been associated to " << nbShape << " shapes" << endl; munmap(mapPtr, length); close(fileOpen); @@ -603,6 +806,18 @@ static bool readResultFile(const int fileOpen, delete [] nodeID; delete [] coord; delete [] node; + delete [] nodeAssigne; + +#ifdef _DEBUG_ + if ( shapeIDs.size() != nbShape ) { + cout << "Only " << shapeIDs.size() << " solids of " << nbShape << " found" << endl; + for (int i=0; iShapeToIndex( tabShape[i] ); + if ( shapeIDs.find( shapeID ) == shapeIDs.end() ) + cout << " Solid #" << shapeID << " not found" << endl; + } + } +#endif return true; } @@ -705,64 +920,6 @@ static bool readResultFile(const int fileOpen, return true; } -//======================================================================= -//function : getTmpDir -//purpose : -//======================================================================= - -static TCollection_AsciiString getTmpDir() -{ - TCollection_AsciiString aTmpDir; - - char *Tmp_dir = getenv("SALOME_TMP_DIR"); - if(Tmp_dir != NULL) { - aTmpDir = Tmp_dir; -#ifdef WIN32 - if(aTmpDir.Value(aTmpDir.Length()) != '\\') aTmpDir+='\\'; -#else - if(aTmpDir.Value(aTmpDir.Length()) != '/') aTmpDir+='/'; -#endif - } - else { -#ifdef WIN32 - aTmpDir = TCollection_AsciiString("C:\\"); -#else - aTmpDir = TCollection_AsciiString("/tmp/"); -#endif - } - return aTmpDir; -} - -//================================================================================ -/*! - * \brief Look for a line containing a text in a file - * \retval bool - true if the line is found - */ -//================================================================================ - -static bool findLineContaing(const TCollection_AsciiString& theText, - const TCollection_AsciiString& theFile, - TCollection_AsciiString & theFoundLine) -{ - bool found = false; - if ( FILE * aFile = fopen( theFile.ToCString(), "r" )) - { - char * aPtr; - char aBuffer[ GHS3DPlugin_BUFLENGTH ]; - int aLineNb = 0; - do { - GHS3DPlugin_ReadLine( aPtr, aBuffer, aFile, aLineNb ); - if ( aPtr ) { - theFoundLine = aPtr; - found = theFoundLine.Search( theText ) >= 0; - } - } while ( aPtr && !found ); - - fclose( aFile ); - } - return found; -} - //============================================================================= /*! *Here we are going to use the GHS3D mesher @@ -800,21 +957,10 @@ bool GHS3DPlugin_GHS3D::Compute(SMESH_Mesh& theMesh, iShape++; } - cout << endl; - cout << "Ghs3d execution..." << endl; - - // make a unique working file name + // a unique working file name // to avoid access to the same files by eg different users - - TCollection_AsciiString aGenericName, aTmpDir = getTmpDir(); - aGenericName = aTmpDir + "GHS3D_"; -#ifdef WIN32 - aGenericName += GetCurrentProcessId(); -#else - aGenericName += getpid(); -#endif - aGenericName += "_"; - aGenericName += meshDS->ShapeToIndex( theShape ); + TCollection_AsciiString aGenericName + = (char*) GHS3DPlugin_Hypothesis::GetFileName(_hyp).c_str(); TCollection_AsciiString aFacesFileName, aPointsFileName, aResultFileName; TCollection_AsciiString aBadResFileName, aBbResFileName, aLogFileName; @@ -839,8 +985,8 @@ bool GHS3DPlugin_GHS3D::Compute(SMESH_Mesh& theMesh, aFacesFile.rdbuf()->is_open() && aPointsFile.rdbuf()->is_open(); #endif if (!Ok) { - INFOS( "Can't write into " << aTmpDir.ToCString()); - return error(SMESH_Comment("Can't write into ") << aTmpDir); + INFOS( "Can't write into " << aFacesFileName); + return error(SMESH_Comment("Can't write into ") << aFacesFileName); } map aSmdsToGhs3dIdMap; map aGhs3dIdToNodeMap; @@ -852,38 +998,25 @@ bool GHS3DPlugin_GHS3D::Compute(SMESH_Mesh& theMesh, aPointsFile.close(); if ( ! Ok ) { - if ( !getenv("GHS3D_KEEP_FILES") ) { + if ( !_keepFiles ) { OSD_File( aFacesFileName ).Remove(); OSD_File( aPointsFileName ).Remove(); } return error(COMPERR_BAD_INPUT_MESH); } + OSD_File( aResultFileName ).Remove(); // needed for boundary recovery module usage // ----------------- - // run ghs3d mesher WIN32??? + // run ghs3d mesher // ----------------- - // ghs3d need to know amount of memory it may use (MB). - // Default memory is defined at ghs3d installation but it may be not enough, - // so allow to use about all available memory - - TCollection_AsciiString memory; -#ifndef WIN32 - struct sysinfo si; - int err = sysinfo( &si ); - if ( err == 0 ) { - int freeMem = si.totalram * si.mem_unit / 1024 / 1024; - memory = "-m "; - memory += int( 0.7 * freeMem ); - } -#endif + 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 - MESSAGE("GHS3DPlugin_GHS3D::Compute"); - TCollection_AsciiString cmd( "ghs3d " ); // command to run - cmd += - memory + // memory - " -c0 -f " + aGenericName + // file to read - " 1>" + aLogFileName; // dump into file + cout << endl; + cout << "Ghs3d execution..." << endl; + cout << cmd << endl; system( cmd.ToCString() ); // run @@ -901,10 +1034,15 @@ bool GHS3DPlugin_GHS3D::Compute(SMESH_Mesh& theMesh, if ( fileOpen < 0 ) { cout << endl; cout << "Can't open the " << aResultFileName.ToCString() << " GHS3D output file" << endl; + cout << "Log: " << aLogFileName << endl; Ok = false; } - else - Ok = readResultFile( fileOpen, meshDS, tabShape, tabBox, _nbShape, aGhs3dIdToNodeMap ); + else { + bool toMeshHoles = + _hyp ? _hyp->GetToMeshHoles(true) : GHS3DPlugin_Hypothesis::DefaultMeshHoles(); + Ok = readResultFile( fileOpen, theMesh, tabShape, tabBox, _nbShape, aGhs3dIdToNodeMap, + toMeshHoles ); + } // --------------------- // remove working files @@ -912,35 +1050,14 @@ bool GHS3DPlugin_GHS3D::Compute(SMESH_Mesh& theMesh, if ( Ok ) { - OSD_File( aLogFileName ).Remove(); + if ( !_keepFiles ) + OSD_File( aLogFileName ).Remove(); } else if ( OSD_File( aLogFileName ).Size() > 0 ) { - INFOS( "GHS3D Error, see the " << aLogFileName.ToCString() << " file" ); - // get problem description from the log file - SMESH_Comment comment; - TCollection_AsciiString foundLine; - if ( findLineContaing( "has expired",aLogFileName,foundLine) && - foundLine.Search("Licence") >= 0) - { - foundLine.LeftAdjust(); - comment << foundLine; - } - if ( findLineContaing( "%% ERROR",aLogFileName,foundLine)) - { - foundLine.LeftAdjust(); - comment << foundLine; - } - if ( findLineContaing( "%% NO SAVING OPERATION",aLogFileName,foundLine)) - { - comment << "Too many elements generated for a trial version.\n"; - } - if ( comment.empty() ) - comment << "See " << aLogFileName << " for problem description"; - else - comment << "See " << aLogFileName << " for more information"; - error(COMPERR_ALGO_FAILED, comment); + _Ghs2smdsConvertor conv( aGhs3dIdToNodeMap ); + storeErrorDescription( aLogFileName, conv ); } else { @@ -950,7 +1067,7 @@ bool GHS3DPlugin_GHS3D::Compute(SMESH_Mesh& theMesh, error(COMPERR_ALGO_FAILED, "ghs3d: command not found" ); } - if ( !getenv("GHS3D_KEEP_FILES") ) { + if ( !_keepFiles ) { OSD_File( aFacesFileName ).Remove(); OSD_File( aPointsFileName ).Remove(); OSD_File( aResultFileName ).Remove(); @@ -983,18 +1100,10 @@ bool GHS3DPlugin_GHS3D::Compute(SMESH_Mesh& theMesh, SMESHDS_Mesh* meshDS = theMesh.GetMeshDS(); TopoDS_Shape theShape = aHelper->GetSubShape(); - // make a unique working file name + // a unique working file name // to avoid access to the same files by eg different users - - TCollection_AsciiString aGenericName, aTmpDir = getTmpDir(); - aGenericName = aTmpDir + "GHS3D_"; -#ifdef WIN32 - aGenericName += GetCurrentProcessId(); -#else - aGenericName += getpid(); -#endif - aGenericName += "_"; - aGenericName += meshDS->ShapeToIndex( theShape ); + TCollection_AsciiString aGenericName + = (char*) GHS3DPlugin_Hypothesis::GetFileName(_hyp).c_str(); TCollection_AsciiString aFacesFileName, aPointsFileName, aResultFileName; TCollection_AsciiString aBadResFileName, aBbResFileName, aLogFileName; @@ -1019,7 +1128,7 @@ bool GHS3DPlugin_GHS3D::Compute(SMESH_Mesh& theMesh, #endif if (!Ok) - return error( SMESH_Comment("Can't write into ") << aTmpDir.ToCString()); + return error( SMESH_Comment("Can't write into ") << aPointsFileName); vector aNodeByGhs3dId; @@ -1030,40 +1139,22 @@ bool GHS3DPlugin_GHS3D::Compute(SMESH_Mesh& theMesh, aPointsFile.close(); if ( ! Ok ) { - if ( !getenv("GHS3D_KEEP_FILES") ) { + if ( !_keepFiles ) { OSD_File( aFacesFileName ).Remove(); OSD_File( aPointsFileName ).Remove(); } return error(COMPERR_BAD_INPUT_MESH); } + OSD_File( aResultFileName ).Remove(); // needed for boundary recovery module usage // ----------------- - // run ghs3d mesher WIN32??? + // run ghs3d mesher // ----------------- - // ghs3d need to know amount of memory it may use (MB). - // Default memory is defined at ghs3d installation but it may be not enough, - // so allow to use about all available memory - TCollection_AsciiString memory; -#ifdef WIN32 - // ???? -#else - struct sysinfo si; - int err = sysinfo( &si ); - if ( !err ) { - int freeMem = si.totalram * si.mem_unit / 1024 / 1024; - memory = "-m "; - memory += int( 0.7 * freeMem ); - } -#endif - - TCollection_AsciiString cmd( "ghs3d " ); // command to run - cmd += - memory + // memory - " -f " + aGenericName + // file to read - " 1>" + aLogFileName; // dump into file - - + 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 @@ -1075,6 +1166,7 @@ bool GHS3DPlugin_GHS3D::Compute(SMESH_Mesh& theMesh, if ( fileOpen < 0 ) { cout << endl; cout << "Error when opening the " << aResultFileName.ToCString() << " file" << endl; + cout << "Log: " << aLogFileName << endl; cout << endl; Ok = false; } @@ -1088,35 +1180,14 @@ bool GHS3DPlugin_GHS3D::Compute(SMESH_Mesh& theMesh, if ( Ok ) { - OSD_File( aLogFileName ).Remove(); + if ( !_keepFiles ) + OSD_File( aLogFileName ).Remove(); } else if ( OSD_File( aLogFileName ).Size() > 0 ) { - INFOS( "GHS3D Error, see the " << aLogFileName.ToCString() << " file" ); - // get problem description from the log file - SMESH_Comment comment; - TCollection_AsciiString foundLine; - if ( findLineContaing( "has expired",aLogFileName,foundLine) && - foundLine.Search("Licence") >= 0) - { - foundLine.LeftAdjust(); - comment << foundLine; - } - if ( findLineContaing( "%% ERROR",aLogFileName,foundLine)) - { - foundLine.LeftAdjust(); - comment << foundLine; - } - if ( findLineContaing( "%% NO SAVING OPERATION",aLogFileName,foundLine)) - { - comment << "Too many elements generated for a trial version.\n"; - } - if ( comment.empty() ) - comment << "See " << aLogFileName << " for problem description"; - else - comment << "See " << aLogFileName << " for more information"; - error(COMPERR_ALGO_FAILED, comment); + _Ghs2smdsConvertor conv( aNodeByGhs3dId ); + storeErrorDescription( aLogFileName, conv ); } else { // the log file is empty @@ -1125,7 +1196,7 @@ bool GHS3DPlugin_GHS3D::Compute(SMESH_Mesh& theMesh, error(COMPERR_ALGO_FAILED, "ghs3d: command not found" ); } - if ( !getenv("GHS3D_KEEP_FILES") ) + if ( !_keepFiles ) { OSD_File( aFacesFileName ).Remove(); OSD_File( aPointsFileName ).Remove(); @@ -1137,46 +1208,492 @@ bool GHS3DPlugin_GHS3D::Compute(SMESH_Mesh& theMesh, return Ok; } -//============================================================================= +//================================================================================ /*! - * + * \brief Provide human readable text by error code reported by ghs3d */ -//============================================================================= +//================================================================================ -ostream & GHS3DPlugin_GHS3D::SaveTo(ostream & save) +static string translateError(const int errNum) { - return save; + 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 */ -//============================================================================= +//================================================================================ -istream & GHS3DPlugin_GHS3D::LoadFrom(istream & load) +static char* getIds( char* ptr, int nbIds, vector& ids ) { - return load; + 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 */ -//============================================================================= +//================================================================================ -ostream & operator << (ostream & save, GHS3DPlugin_GHS3D & hyp) +bool GHS3DPlugin_GHS3D::storeErrorDescription(const TCollection_AsciiString& logFile, + const _Ghs2smdsConvertor & toSmdsConvertor ) { - return hyp.SaveTo( save ); + // 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."; + } + + 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 ) +{ +} -istream & operator >> (istream & load, GHS3DPlugin_GHS3D & hyp) +//================================================================================ +/*! + * \brief Creates _Ghs2smdsConvertor + */ +//================================================================================ + +_Ghs2smdsConvertor::_Ghs2smdsConvertor( const vector & nodeByGhsId) + : _ghs2NodeMap( 0 ), _nodeByGhsId( &nodeByGhsId ) { - return hyp.LoadFrom( load ); } + +//================================================================================ +/*! + * \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_MeshEdge( 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; +} + diff --git a/src/GHS3DPlugin_GHS3D.hxx b/src/GHS3DPlugin_GHS3D.hxx index 05a3e10..bb37df5 100644 --- a/src/GHS3DPlugin_GHS3D.hxx +++ b/src/GHS3DPlugin_GHS3D.hxx @@ -29,7 +29,14 @@ #include "SMESH_3D_Algo.hxx" +#include +#include + class SMESH_Mesh; +class GHS3DPlugin_Hypothesis; +class SMDS_MeshNode; +class TCollection_AsciiString; +class _Ghs2smdsConvertor; class GHS3DPlugin_GHS3D: public SMESH_3D_Algo { @@ -37,24 +44,41 @@ public: GHS3DPlugin_GHS3D(int hypId, int studyId, SMESH_Gen* gen); virtual ~GHS3DPlugin_GHS3D(); - virtual bool CheckHypothesis(SMESH_Mesh& aMesh, - const TopoDS_Shape& aShape, - SMESH_Hypothesis::Hypothesis_Status& aStatus); + virtual bool CheckHypothesis(SMESH_Mesh& aMesh, + const TopoDS_Shape& aShape, + Hypothesis_Status& aStatus); virtual bool Compute(SMESH_Mesh& aMesh, - const TopoDS_Shape& aShape); + const TopoDS_Shape& aShape); virtual bool Compute(SMESH_Mesh& theMesh, SMESH_MesherHelper* aHelper); - ostream & SaveTo(ostream & save); - istream & LoadFrom(istream & load); - friend ostream & operator << (ostream & save, GHS3DPlugin_GHS3D & hyp); - friend istream & operator >> (istream & load, GHS3DPlugin_GHS3D & hyp); - private: - int _iShape; - int _nbShape; + + bool storeErrorDescription(const TCollection_AsciiString& logFile, + const _Ghs2smdsConvertor & toSmdsConvertor ); + + int _iShape; + int _nbShape; + bool _keepFiles; + const GHS3DPlugin_Hypothesis* _hyp; +}; + +/*! + * \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_Hypothesis.cxx b/src/GHS3DPlugin_Hypothesis.cxx new file mode 100644 index 0000000..525b3db --- /dev/null +++ b/src/GHS3DPlugin_Hypothesis.cxx @@ -0,0 +1,616 @@ +// Copyright (C) 2005 CEA/DEN, EDF R&D, OPEN CASCADE, PRINCIPIA 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 + +//======================================================================= +//function : GHS3DPlugin_Hypothesis +//======================================================================= + +GHS3DPlugin_Hypothesis::GHS3DPlugin_Hypothesis(int hypId, int studyId, SMESH_Gen * gen) + : SMESH_Hypothesis(hypId, studyId, gen) +{ + _name = "GHS3D_Parameters"; + _param_algo_dim = 3; + + myToMeshHoles = DefaultMeshHoles(); + myMaximumMemory = -1;//DefaultMaximumMemory(); + myInitialMemory = -1;//DefaultInitialMemory(); + myOptimizationLevel = DefaultOptimizationLevel(); + myWorkingDirectory = DefaultWorkingDirectory(); + myKeepFiles = DefaultKeepFiles(); + myVerboseLevel = DefaultVerboseLevel(); + myToCreateNewNodes = DefaultToCreateNewNodes(); + myToUseBoundaryRecoveryVersion = DefaultToUseBoundaryRecoveryVersion(); +} + +//======================================================================= +//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 string& path) +{ + if ( myWorkingDirectory != path ) { + myWorkingDirectory = path; + NotifySubMeshesHypothesisModification(); + } +} + +//======================================================================= +//function : GetWorkingDirectory +//======================================================================= + +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 : SetTextOption +//======================================================================= + +void GHS3DPlugin_Hypothesis::SetTextOption(const string& option) +{ + if ( myTextOption != option ) { + myTextOption = option; + NotifySubMeshesHypothesisModification(); + } +} + +//======================================================================= +//function : GetTextOption +//======================================================================= + +string GHS3DPlugin_Hypothesis::GetTextOption() const +{ + return myTextOption; +} + + +//======================================================================= +//function : DefaultMeshHoles +//======================================================================= + +bool GHS3DPlugin_Hypothesis::DefaultMeshHoles() +{ + return false; // PAL19680 +} + +//======================================================================= +//function : DefaultMaximumMemory +//======================================================================= + +#ifndef WIN32 +#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 (short) ( 0.7 * ramMB ); + } +#endif + return -1; +} + +//======================================================================= +//function : DefaultInitialMemory +//======================================================================= + +short GHS3DPlugin_Hypothesis::DefaultInitialMemory() +{ + return DefaultMaximumMemory(); +} + +//======================================================================= +//function : DefaultOptimizationLevel +//======================================================================= + +short GHS3DPlugin_Hypothesis::DefaultOptimizationLevel() +{ + return Medium; +} + +//======================================================================= +//function : DefaultWorkingDirectory +//======================================================================= + +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 : SaveTo +//======================================================================= + +ostream & GHS3DPlugin_Hypothesis::SaveTo(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 << myTextOption << " "; + return save; +} + +//======================================================================= +//function : LoadFrom +//======================================================================= + +istream & GHS3DPlugin_Hypothesis::LoadFrom(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 >> myTextOption); + while (isOK) { + string txt; + if (load >> txt) { + myTextOption += " "; + myTextOption += txt; + } + else + isOK = false; + } +// else +// load.clear(ios::badbit | load.rdstate()); + + return load; +} + +//======================================================================= +//function : SetParametersByMesh +//======================================================================= + +bool GHS3DPlugin_Hypothesis::SetParametersByMesh(const SMESH_Mesh* ,const TopoDS_Shape&) +{ + return false; +} + +//================================================================================ +/*! + * \brief Return command to run ghs3d mesher excluding file prefix (-f) + */ +//================================================================================ + +string GHS3DPlugin_Hypothesis::CommandToRun(const GHS3DPlugin_Hypothesis* hyp, + const bool hasShapeToMesh) +{ +#ifndef WIN32 + TCollection_AsciiString cmd( "ghs3d" ); +#else + TCollection_AsciiString cmd( "ghs3d.exe" ); +#endif + // check if any option is overridden by hyp->myTextOption + bool m = hyp ? ( hyp->myTextOption.find("-m") == string::npos ) : true; + bool M = hyp ? ( hyp->myTextOption.find("-M") == string::npos ) : true; + bool c = hyp ? ( hyp->myTextOption.find("-c") == string::npos ) : true; + bool o = hyp ? ( hyp->myTextOption.find("-o") == string::npos ) : true; + bool p0= hyp ? ( hyp->myTextOption.find("-p0")== string::npos ) : true; + bool C = hyp ? ( hyp->myTextOption.find("-C") == string::npos ) : true; + bool v = hyp ? ( hyp->myTextOption.find("-v") == 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 < 4 ) { + char* level[] = { "none" , "light" , "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"; + } + + // options as text + if ( hyp && !hyp->myTextOption.empty() ) { + cmd += " "; + cmd += (char*) hyp->myTextOption.c_str(); + } + + return cmd.ToCString(); +} + +//================================================================================ +/*! + * \brief Return a unique file name + */ +//================================================================================ + +string GHS3DPlugin_Hypothesis::GetFileName(const GHS3DPlugin_Hypothesis* hyp) +{ + 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_"; +#ifdef WIN32 + aGenericName += GetCurrentProcessId(); +#else + aGenericName += getpid(); +#endif + aGenericName += "_"; + aGenericName += Abs((Standard_Integer)(long) aGenericName.ToCString()); + + return aGenericName.ToCString(); +} diff --git a/src/GHS3DPlugin_Hypothesis.hxx b/src/GHS3DPlugin_Hypothesis.hxx new file mode 100644 index 0000000..a50d11a --- /dev/null +++ b/src/GHS3DPlugin_Hypothesis.hxx @@ -0,0 +1,146 @@ +// GHS3DPlugin : C++ implementation +// +// Copyright (C) 2006 OPEN CASCADE, 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 + +// 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 + +using namespace std; + +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-strong. Default is medium + */ + enum OptimizationLevel { None = 0, Light, Medium, Strong }; + void SetOptimizationLevel(OptimizationLevel level); + OptimizationLevel GetOptimizationLevel() const; + /*! + * Path to working directory + */ + void SetWorkingDirectory(const string& path); + 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; + /*! + * To set hiden/undocumented/advanced options + */ + void SetTextOption(const string& option); + string GetTextOption() const; + + static bool DefaultMeshHoles(); + static short DefaultMaximumMemory(); + static short DefaultInitialMemory(); + static short DefaultOptimizationLevel(); + static string DefaultWorkingDirectory(); + static bool DefaultKeepFiles(); + static short DefaultVerboseLevel(); + static bool DefaultToCreateNewNodes(); + static bool DefaultToUseBoundaryRecoveryVersion(); + + /*! + * \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); + + // Persistence + virtual ostream & SaveTo(ostream & save); + virtual istream & LoadFrom(istream & load); + friend GHS3DPLUGIN_EXPORT ostream & operator <<(ostream & save, GHS3DPlugin_Hypothesis & hyp); + friend GHS3DPLUGIN_EXPORT istream & operator >>(istream & load, GHS3DPlugin_Hypothesis & hyp); + + /*! + * \brief Does nothing + */ + virtual bool SetParametersByMesh(const SMESH_Mesh* theMesh, const TopoDS_Shape& theShape); + +private: + + bool myToMeshHoles; + short myMaximumMemory; + short myInitialMemory; + short myOptimizationLevel; + bool myKeepFiles; + string myWorkingDirectory; + short myVerboseLevel; + bool myToCreateNewNodes; + bool myToUseBoundaryRecoveryVersion; + string myTextOption; + +}; + + +#endif diff --git a/src/GHS3DPlugin_Hypothesis_i.cxx b/src/GHS3DPlugin_Hypothesis_i.cxx new file mode 100644 index 0000000..cbedd2d --- /dev/null +++ b/src/GHS3DPlugin_Hypothesis_i.cxx @@ -0,0 +1,301 @@ +// 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 : 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() ); +} + +//============================================================================= +/*! + * 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 new file mode 100644 index 0000000..f86e4f4 --- /dev/null +++ b/src/GHS3DPlugin_Hypothesis_i.hxx @@ -0,0 +1,120 @@ +// GHS3DPlugin : C++ implementation +// +// Copyright (C) 2006 OPEN CASCADE, 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.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(); + /*! + * To set hiden/undocumented/advanced options + */ + void SetTextOption(const char* option); + char* GetTextOption(); + + // 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 index 1622f60..ff53dba 100644 --- a/src/GHS3DPlugin_i.cxx +++ b/src/GHS3DPlugin_i.cxx @@ -32,6 +32,7 @@ using namespace std; #include "utilities.h" #include "GHS3DPlugin_GHS3D_i.hxx" +#include "GHS3DPlugin_Hypothesis_i.hxx" template class GHS3DPlugin_Creator_i:public HypothesisCreator_i { @@ -55,9 +56,12 @@ extern "C" // Hypotheses - // Algorithms + // 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_icons.po b/src/GHS3DPlugin_icons.po deleted file mode 100644 index a03d771..0000000 --- a/src/GHS3DPlugin_icons.po +++ /dev/null @@ -1,36 +0,0 @@ -# Copyright (C) 2005 CEA/DEN, EDF R&D, OPEN CASCADE, PRINCIPIA 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 -# -# This is a Qt message file in .po format. Each msgid starts with -# a scope. This scope should *NOT* be translated - eg. "Foo::Bar" -# would be translated to "Pub", not "Foo::Pub". -msgid "" -msgstr "" -"Project-Id-Version: PROJECT VERSION\n" -"POT-Creation-Date: 2002-05-28 10:57:43 AM CEST\n" -"PO-Revision-Date: 2004-03-30 17:24+0400\n" -"Last-Translator: FULLNAME \n" -"Content-Type: text/plain; charset=iso-8859-1\n" - - -#----------------------------------------------------------- -# ObjectBrowser -#----------------------------------------------------------- - -msgid "ICON_SMESH_TREE_ALGO_GHS3D_3D" -msgstr "mesh_tree_algo_tetra.png" diff --git a/src/GHS3DPlugin_icons.ts b/src/GHS3DPlugin_icons.ts deleted file mode 100755 index 8427655..0000000 --- a/src/GHS3DPlugin_icons.ts +++ /dev/null @@ -1,10 +0,0 @@ - - - - @default - - ICON_SMESH_TREE_ALGO_GHS3D_3D - mesh_tree_algo_tetra.png - - - diff --git a/src/GUI/GHS3DPluginGUI_HypothesisCreator.cxx b/src/GUI/GHS3DPluginGUI_HypothesisCreator.cxx new file mode 100644 index 0000000..773aad9 --- /dev/null +++ b/src/GUI/GHS3DPluginGUI_HypothesisCreator.cxx @@ -0,0 +1,410 @@ +// GHS3DPlugin GUI: GUI for plugged-in mesher GHS3DPlugin +// +// Copyright (C) 2003 CEA +// +// 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 : GHS3DPluginGUI_HypothesisCreator.cxx +// Author : Michael Zorin +// Module : GHS3DPlugin +// $Header: + +#include "GHS3DPluginGUI_HypothesisCreator.h" + +#include +#include + +#include CORBA_SERVER_HEADER(GHS3DPlugin_Algorithm) + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +enum { + STD_TAB = 0, + ADV_TAB +}; + +namespace { + +#ifndef WIN32 +#include +#endif + + int maxAvailableMemory() + { +#ifndef WIN32 + struct sysinfo si; + int err = sysinfo( &si ); + if ( err == 0 ) { + int totMB = + si.totalram * si.mem_unit / 1024 / 1024 + + si.totalswap * si.mem_unit / 1024 / 1024 ; + return (int) ( 0.7 * totMB ); + } +#endif + return 100000; + } +} + +GHS3DPluginGUI_HypothesisCreator::GHS3DPluginGUI_HypothesisCreator( const QString& theHypType ) +: SMESHGUI_GenericHypothesisCreator( theHypType ) +{ +} + +GHS3DPluginGUI_HypothesisCreator::~GHS3DPluginGUI_HypothesisCreator() +{ +} + +QFrame* GHS3DPluginGUI_HypothesisCreator::buildFrame() +{ + QFrame* fr = new QFrame( 0 ); + QVBoxLayout* lay = new QVBoxLayout( fr ); + lay->setMargin( 5 ); + lay->setSpacing( 0 ); + + // tab + QTabWidget* tab = new QTabWidget( fr ); + tab->setTabShape( QTabWidget::Rounded ); + tab->setTabPosition( QTabWidget::North ); + lay->addWidget( tab ); + + // basic parameters + myStdGroup = new QWidget(); + QGridLayout* aStdLayout = new QGridLayout( myStdGroup ); + aStdLayout->setSpacing( 6 ); + aStdLayout->setMargin( 11 ); + + int row = 0; + myName = 0; + if( isCreation() ) + { + aStdLayout->addWidget( new QLabel( tr( "SMESH_NAME" ), myStdGroup ), row, 0, 1, 1 ); + myName = new QLineEdit( myStdGroup ); + aStdLayout->addWidget( myName, row++, 1, 1, 1 ); + } + + myToMeshHolesCheck = new QCheckBox( tr( "GHS3D_TO_MESH_HOLES" ), myStdGroup ); + aStdLayout->addWidget( myToMeshHolesCheck, row++, 0, 1, 2 ); + + aStdLayout->addWidget( new QLabel( tr( "GHS3D_OPTIMIZATIOL_LEVEL" ), myStdGroup ), row, 0 ); + myOptimizationLevelCombo = new QComboBox( myStdGroup ); + aStdLayout->addWidget( myOptimizationLevelCombo, row++, 1, 1, 1 ); + + QStringList types; + types << tr( "LEVEL_NONE" ) << tr( "LEVEL_LIGHT" ) << tr( "LEVEL_MEDIUM" ) << tr( "LEVEL_STRONG" ); + myOptimizationLevelCombo->addItems( types ); + + aStdLayout->setRowStretch( row, 5 ); + + // advanced parameters + myAdvGroup = new QWidget(); + QGridLayout* anAdvLayout = new QGridLayout( myAdvGroup ); + anAdvLayout->setSpacing( 6 ); + anAdvLayout->setMargin( 11 ); + + myMaximumMemoryCheck = new QCheckBox( tr( "MAX_MEMORY_SIZE" ), myAdvGroup ); + myMaximumMemorySpin = new QSpinBox( myAdvGroup ); + myMaximumMemorySpin->setMinimum( 1 ); + myMaximumMemorySpin->setMaximum( maxAvailableMemory() ); + myMaximumMemorySpin->setSingleStep( 10 ); + QLabel* aMegabyteLabel = new QLabel( tr( "MEGABYTE" ), myAdvGroup ); + + myInitialMemoryCheck = new QCheckBox( tr( "INIT_MEMORY_SIZE" ), myAdvGroup ); + myInitialMemorySpin = new QSpinBox( myAdvGroup ); + myInitialMemorySpin->setMinimum( 1 ); + myInitialMemorySpin->setMaximum( maxAvailableMemory() ); + myInitialMemorySpin->setSingleStep( 10 ); + QLabel* aMegabyteLabel2 = new QLabel( tr( "MEGABYTE" ), myAdvGroup ); + + QLabel* aWorkinDirLabel = new QLabel( tr( "WORKING_DIR" ), myAdvGroup ); + myWorkingDir = new QLineEdit( myAdvGroup ); + //myWorkingDir->setReadOnly( true ); + QPushButton* dirBtn = new QPushButton( tr( "SELECT_DIR" ), myAdvGroup ); + dirBtn->setSizePolicy( QSizePolicy( QSizePolicy::Fixed, QSizePolicy::Fixed ) ); + + myKeepFiles = new QCheckBox( tr( "KEEP_WORKING_FILES" ), myAdvGroup ); + + QLabel* aVerboseLevelLabel = new QLabel( tr( "VERBOSE_LEVEL" ), myAdvGroup ); + myVerboseLevelSpin = new QSpinBox( myAdvGroup ); + myVerboseLevelSpin->setMinimum( 0 ); + myVerboseLevelSpin->setMaximum( 10 ); + myVerboseLevelSpin->setSingleStep( 1 ); + + myToCreateNewNodesCheck = new QCheckBox( tr( "TO_ADD_NODES" ), myAdvGroup ); + + myBoundaryRecoveryCheck = new QCheckBox( tr( "RECOVERY_VERSION" ), myAdvGroup ); + + QLabel* aTextOptionLabel = new QLabel( tr( "TEXT_OPTION" ), myAdvGroup ); + myTextOption = new QLineEdit( myAdvGroup ); + + anAdvLayout->addWidget( myMaximumMemoryCheck, 0, 0, 1, 1 ); + anAdvLayout->addWidget( myMaximumMemorySpin, 0, 1, 1, 1 ); + anAdvLayout->addWidget( aMegabyteLabel, 0, 2, 1, 1 ); + anAdvLayout->addWidget( myInitialMemoryCheck, 1, 0, 1, 1 ); + anAdvLayout->addWidget( myInitialMemorySpin, 1, 1, 1, 1 ); + anAdvLayout->addWidget( aMegabyteLabel2, 1, 2, 1, 1 ); + anAdvLayout->addWidget( aWorkinDirLabel, 2, 0, 1, 1 ); + anAdvLayout->addWidget( myWorkingDir, 2, 1, 1, 2 ); + anAdvLayout->addWidget( dirBtn, 2, 3, 1, 1 ); + anAdvLayout->addWidget( myKeepFiles, 3, 0, 1, 4 ); + anAdvLayout->addWidget( aVerboseLevelLabel, 4, 0, 1, 1 ); + anAdvLayout->addWidget( myVerboseLevelSpin, 4, 1, 1, 1 ); + anAdvLayout->addWidget( myToCreateNewNodesCheck, 5, 0, 1, 4 ); + anAdvLayout->addWidget( myBoundaryRecoveryCheck, 6, 0, 1, 4 ); + anAdvLayout->addWidget( aTextOptionLabel, 7, 0, 1, 1 ); + anAdvLayout->addWidget( myTextOption, 7, 1, 1, 2 ); + + // add tabs + tab->insertTab( STD_TAB, myStdGroup, tr( "SMESH_ARGUMENTS" ) ); + tab->insertTab( ADV_TAB, myAdvGroup, tr( "GHS3D_ADV_ARGS" ) ); + tab->setCurrentIndex( STD_TAB ); + + // connections + connect( myMaximumMemoryCheck, SIGNAL( toggled( bool ) ), this, SLOT( updateWidgets() ) ); + connect( myInitialMemoryCheck, SIGNAL( toggled( bool ) ), this, SLOT( updateWidgets() ) ); + connect( myBoundaryRecoveryCheck, SIGNAL( toggled( bool ) ), this, SLOT( updateWidgets() ) ); + connect( dirBtn, SIGNAL( clicked() ), this, SLOT( onDirBtnClicked() ) ); + + return fr; +} + +void GHS3DPluginGUI_HypothesisCreator::onDirBtnClicked() +{ + QString dir = SUIT_FileDlg::getExistingDirectory( dlg(), myWorkingDir->text(), QString() ); + if ( !dir.isEmpty() ) + myWorkingDir->setText( dir ); +} + +void GHS3DPluginGUI_HypothesisCreator::updateWidgets() +{ + myMaximumMemorySpin->setEnabled( myMaximumMemoryCheck->isChecked() ); + myInitialMemoryCheck->setEnabled( !myBoundaryRecoveryCheck->isChecked() ); + myInitialMemorySpin->setEnabled( myInitialMemoryCheck->isChecked() && !myBoundaryRecoveryCheck->isChecked() ); + myOptimizationLevelCombo->setEnabled( !myBoundaryRecoveryCheck->isChecked() ); +} + +bool GHS3DPluginGUI_HypothesisCreator::checkParams() const +{ + if ( !QFileInfo( myWorkingDir->text().trimmed() ).isWritable() ) { + SUIT_MessageBox::warning( dlg(), + tr( "SMESH_WRN_WARNING" ), + tr( "GHS3D_PERMISSION_DENIED" ) ); + return false; + } + return true; +} + +void GHS3DPluginGUI_HypothesisCreator::retrieveParams() const +{ + GHS3DHypothesisData data; + readParamsFromHypo( data ); + + if ( myName ) + myName->setText( data.myName ); + + myToMeshHolesCheck ->setChecked ( data.myToMeshHoles ); + myOptimizationLevelCombo->setCurrentIndex( data.myOptimizationLevel ); + myMaximumMemoryCheck ->setChecked ( data.myMaximumMemory > 0 ); + myMaximumMemorySpin ->setValue ( qMax( data.myMaximumMemory, + myMaximumMemorySpin->minimum() )); + myInitialMemoryCheck ->setChecked ( data.myInitialMemory > 0 ); + myInitialMemorySpin ->setValue ( qMax( data.myInitialMemory, + myInitialMemorySpin->minimum() )); + myWorkingDir ->setText ( data.myWorkingDir ); + myKeepFiles ->setChecked ( data.myKeepFiles ); + myVerboseLevelSpin ->setValue ( data.myVerboseLevel ); + myToCreateNewNodesCheck ->setChecked ( data.myToCreateNewNodes ); + myBoundaryRecoveryCheck ->setChecked ( data.myBoundaryRecovery ); + myTextOption ->setText ( data.myTextOption ); + + GHS3DPluginGUI_HypothesisCreator* that = (GHS3DPluginGUI_HypothesisCreator*)this; + that->updateWidgets(); +} + +QString GHS3DPluginGUI_HypothesisCreator::storeParams() const +{ + GHS3DHypothesisData data; + readParamsFromWidgets( data ); + storeParamsToHypo( data ); + + QString valStr = ""; + + if ( !data.myBoundaryRecovery ) + valStr = "-c " + QString::number( !data.myToMeshHoles ); + + if ( data.myOptimizationLevel >= 0 && data.myOptimizationLevel < 4 && !data.myBoundaryRecovery) { + char* level[] = { "none" , "light" , "standard" , "strong" }; + valStr += " -o "; + valStr += level[ data.myOptimizationLevel ]; + } + if ( data.myMaximumMemory > 0 ) { + valStr += " -m "; + valStr += QString::number( data.myMaximumMemory ); + } + if ( data.myInitialMemory > 0 && !data.myBoundaryRecovery ) { + valStr += " -M "; + valStr += QString::number( data.myInitialMemory ); + } + valStr += " -v "; + valStr += QString::number( data.myVerboseLevel ); + + if ( !data.myToCreateNewNodes ) + valStr += " -p0"; + + if ( data.myBoundaryRecovery ) + valStr += " -C"; + + valStr += " "; + valStr += data.myTextOption; + + return valStr; +} + +bool GHS3DPluginGUI_HypothesisCreator::readParamsFromHypo( GHS3DHypothesisData& h_data ) const +{ + GHS3DPlugin::GHS3DPlugin_Hypothesis_var h = + GHS3DPlugin::GHS3DPlugin_Hypothesis::_narrow( initParamsHypothesis() ); + + HypothesisData* data = SMESH::GetHypothesisData( hypType() ); + h_data.myName = isCreation() && data ? hypName() : ""; + + h_data.myToMeshHoles = h->GetToMeshHoles(); + h_data.myMaximumMemory = h->GetMaximumMemory(); + h_data.myInitialMemory = h->GetInitialMemory(); + h_data.myInitialMemory = h->GetInitialMemory(); + h_data.myOptimizationLevel = h->GetOptimizationLevel(); + h_data.myKeepFiles = h->GetKeepFiles(); + h_data.myWorkingDir = h->GetWorkingDirectory(); + h_data.myVerboseLevel = h->GetVerboseLevel(); + h_data.myToCreateNewNodes = h->GetToCreateNewNodes(); + h_data.myBoundaryRecovery = h->GetToUseBoundaryRecoveryVersion(); + h_data.myTextOption = h->GetTextOption(); + + return true; +} + +bool GHS3DPluginGUI_HypothesisCreator::storeParamsToHypo( const GHS3DHypothesisData& h_data ) const +{ + GHS3DPlugin::GHS3DPlugin_Hypothesis_var h = + GHS3DPlugin::GHS3DPlugin_Hypothesis::_narrow( hypothesis() ); + + bool ok = true; + try + { + if( isCreation() ) + SMESH::SetName( SMESH::FindSObject( h ), h_data.myName.toLatin1().constData() ); + + if ( h->GetToMeshHoles() != h_data.myToMeshHoles ) // avoid duplication of DumpPython commands + h->SetToMeshHoles ( h_data.myToMeshHoles ); + if ( h->GetMaximumMemory() != h_data.myMaximumMemory ) + h->SetMaximumMemory ( h_data.myMaximumMemory ); + if ( h->GetInitialMemory() != h_data.myInitialMemory ) + h->SetInitialMemory ( h_data.myInitialMemory ); + if ( h->GetInitialMemory() != h_data.myInitialMemory ) + h->SetInitialMemory ( h_data.myInitialMemory ); + if ( h->GetOptimizationLevel() != h_data.myOptimizationLevel ) + h->SetOptimizationLevel( h_data.myOptimizationLevel ); + if ( h->GetKeepFiles() != h_data.myKeepFiles ) + h->SetKeepFiles ( h_data.myKeepFiles ); + if ( h->GetWorkingDirectory() != h_data.myWorkingDir ) + h->SetWorkingDirectory ( h_data.myWorkingDir.toLatin1().constData() ); + if ( h->GetVerboseLevel() != h_data.myVerboseLevel ) + h->SetVerboseLevel ( h_data.myVerboseLevel ); + if ( h->GetToCreateNewNodes() != h_data.myToCreateNewNodes ) + h->SetToCreateNewNodes( h_data.myToCreateNewNodes ); + if ( h->GetToUseBoundaryRecoveryVersion() != h_data.myBoundaryRecovery ) + h->SetToUseBoundaryRecoveryVersion( h_data.myBoundaryRecovery ); + if ( h->GetTextOption() != h_data.myTextOption ) + h->SetTextOption ( h_data.myTextOption.toLatin1().constData() ); + } + catch ( const SALOME::SALOME_Exception& ex ) + { + SalomeApp_Tools::QtCatchCorbaException( ex ); + ok = false; + } + return ok; +} + +bool GHS3DPluginGUI_HypothesisCreator::readParamsFromWidgets( GHS3DHypothesisData& h_data ) const +{ + h_data.myName = myName ? myName->text() : ""; + h_data.myToMeshHoles = myToMeshHolesCheck->isChecked(); + h_data.myMaximumMemory = myMaximumMemoryCheck->isChecked() ? myMaximumMemorySpin->value() : -1; + h_data.myInitialMemory = myInitialMemoryCheck->isChecked() ? myInitialMemorySpin->value() : -1; + h_data.myOptimizationLevel = myOptimizationLevelCombo->currentIndex(); + h_data.myKeepFiles = myKeepFiles->isChecked(); + h_data.myWorkingDir = myWorkingDir->text().trimmed(); + h_data.myVerboseLevel = myVerboseLevelSpin->value(); + h_data.myToCreateNewNodes = myToCreateNewNodesCheck->isChecked(); + h_data.myBoundaryRecovery = myBoundaryRecoveryCheck->isChecked(); + h_data.myTextOption = myTextOption->text(); + + return true; +} + +QString GHS3DPluginGUI_HypothesisCreator::caption() const +{ + return tr( "GHS3D_TITLE" ); +} + +QPixmap GHS3DPluginGUI_HypothesisCreator::icon() const +{ + return SUIT_Session::session()->resourceMgr()->loadPixmap( "GHS3DPlugin", tr( "ICON_DLG_GHS3D_PARAMETERS" ) ); +} + +QString GHS3DPluginGUI_HypothesisCreator::type() const +{ + return tr( "GHS3D_HYPOTHESIS" ); +} + +QString GHS3DPluginGUI_HypothesisCreator::helpPage() const +{ + return "ghs3d_hypo_page.html"; +} + +//============================================================================= +/*! GetHypothesisCreator + * + */ +//============================================================================= +extern "C" +{ + GHS3DPLUGIN_EXPORT + SMESHGUI_GenericHypothesisCreator* GetHypothesisCreator( const QString& aHypType ) + { + if ( aHypType == "GHS3D_Parameters" ) + return new GHS3DPluginGUI_HypothesisCreator( aHypType ); + return 0; + } +} diff --git a/src/GUI/GHS3DPluginGUI_HypothesisCreator.h b/src/GUI/GHS3DPluginGUI_HypothesisCreator.h new file mode 100644 index 0000000..3568f59 --- /dev/null +++ b/src/GUI/GHS3DPluginGUI_HypothesisCreator.h @@ -0,0 +1,106 @@ +// GHS3DPlugin GUI: GUI for plugged-in mesher GHS3DPlugin +// +// Copyright (C) 2003 CEA +// +// 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 : GHS3DPluginGUI_HypothesisCreator.h +// Author : Michael Zorin +// Module : GHS3DPlugin + +#ifndef GHS3DPLUGINGUI_HypothesisCreator_HeaderFile +#define GHS3DPLUGINGUI_HypothesisCreator_HeaderFile + +#include "GHS3DPlugin_Defs.hxx" +#include + +class QWidget; +class QComboBox; +class QCheckBox; +class QLineEdit; +class QSpinBox; + +typedef struct +{ + bool myToMeshHoles; + int myMaximumMemory; + int myInitialMemory; + int myOptimizationLevel; + bool myKeepFiles; + QString myWorkingDir; + QString myName; + short myVerboseLevel; + bool myToCreateNewNodes; + bool myBoundaryRecovery; + QString myTextOption; + +} GHS3DHypothesisData; + +/*! + \brief Class for creation of GHS3D2D and GHS3D3D hypotheses +*/ +class GHS3DPLUGIN_EXPORT GHS3DPluginGUI_HypothesisCreator : public SMESHGUI_GenericHypothesisCreator +{ + Q_OBJECT + +public: + GHS3DPluginGUI_HypothesisCreator( const QString& ); + virtual ~GHS3DPluginGUI_HypothesisCreator(); + + virtual bool checkParams() const; + virtual QString helpPage() const; + +protected: + virtual QFrame* buildFrame (); + virtual void retrieveParams() const; + virtual QString storeParams () const; + + virtual QString caption() const; + virtual QPixmap icon() const; + virtual QString type() const; + +protected slots: + void onDirBtnClicked(); + void updateWidgets(); + +private: + bool readParamsFromHypo( GHS3DHypothesisData& ) const; + bool readParamsFromWidgets( GHS3DHypothesisData& ) const; + bool storeParamsToHypo( const GHS3DHypothesisData& ) const; + +private: + QWidget* myStdGroup; + QLineEdit* myName; + QCheckBox* myToMeshHolesCheck; + QComboBox* myOptimizationLevelCombo; + + QWidget* myAdvGroup; + QCheckBox* myMaximumMemoryCheck; + QSpinBox* myMaximumMemorySpin; + QCheckBox* myInitialMemoryCheck; + QSpinBox* myInitialMemorySpin; + QLineEdit* myWorkingDir; + QCheckBox* myKeepFiles; + QSpinBox* myVerboseLevelSpin; + QCheckBox* myToCreateNewNodesCheck; + QCheckBox* myBoundaryRecoveryCheck; + QLineEdit* myTextOption; +}; + +#endif diff --git a/src/GUI/GHS3DPlugin_images.ts b/src/GUI/GHS3DPlugin_images.ts new file mode 100644 index 0000000..685f458 --- /dev/null +++ b/src/GUI/GHS3DPlugin_images.ts @@ -0,0 +1,18 @@ + + + + @default + + ICON_DLG_GHS3D_PARAMETERS + mesh_hypo_ghs3d.png + + + ICON_SMESH_TREE_ALGO_GHS3D_3D + mesh_tree_hypo_ghs3d.png + + + ICON_SMESH_TREE_HYPO_GHS3D_Parameters + mesh_tree_hypo_ghs3d.png + + + diff --git a/src/GUI/GHS3DPlugin_msg_en.ts b/src/GUI/GHS3DPlugin_msg_en.ts new file mode 100644 index 0000000..bd612f9 --- /dev/null +++ b/src/GUI/GHS3DPlugin_msg_en.ts @@ -0,0 +1,90 @@ + + + + @default + + GHS3D_ADV_ARGS + Advanced + + + GHS3D_HYPOTHESIS + GHS3D + + + GHS3D_OPTIMIZATIOL_LEVEL + Optimization level + + + GHS3D_PERMISSION_DENIED + Working directory is not writable + + + GHS3D_STD_ARGS + Parameters + + + GHS3D_TITLE + Hypothesis Construction + + + GHS3D_TO_MESH_HOLES + To mesh holes + + + INIT_MEMORY_SIZE + Initial memory size + + + KEEP_WORKING_FILES + To keep working files + + + LEVEL_LIGHT + Light + + + LEVEL_MEDIUM + Medium (standard) + + + LEVEL_NONE + None + + + LEVEL_STRONG + Strong + + + MAX_MEMORY_SIZE + Maximum memory size + + + MEGABYTE + Megabytes + + + RECOVERY_VERSION + To use boundary recovery version + + + SELECT_DIR + ... + + + TEXT_OPTION + Option as text + + + TO_ADD_NODES + To create new nodes + + + VERBOSE_LEVEL + Verbose level + + + WORKING_DIR + Working directory + + + diff --git a/src/GUI/Makefile.am b/src/GUI/Makefile.am new file mode 100644 index 0000000..0169fe2 --- /dev/null +++ b/src/GUI/Makefile.am @@ -0,0 +1,64 @@ +# Copyright (C) 2005 CEA/DEN, EDF R&D, OPEN CASCADE, PRINCIPIA 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 = + +# Libraries targets +lib_LTLIBRARIES = libGHS3DPluginGUI.la + +dist_libGHS3DPluginGUI_la_SOURCES = GHS3DPluginGUI_HypothesisCreator.cxx + +MOC_FILES = GHS3DPluginGUI_HypothesisCreator_moc.cxx +nodist_libGHS3DPluginGUI_la_SOURCES= $(MOC_FILES) + +libGHS3DPluginGUI_la_CPPFLAGS = \ + $(QT_INCLUDES) \ + $(KERNEL_CXXFLAGS) \ + $(GUI_CXXFLAGS) \ + $(GEOM_CXXFLAGS) \ + $(MED_CXXFLAGS) \ + $(SMESH_CXXFLAGS) \ + $(BOOST_CPPFLAGS) \ + $(CORBA_CXXFLAGS) \ + $(CORBA_INCLUDES) \ + $(CAS_CPPFLAGS) \ + -I$(srcdir)/.. \ + -I$(top_builddir)/idl \ + -I$(top_builddir)/salome_adm/unix + +libGHS3DPluginGUI_la_LDFLAGS = \ + ../../idl/libSalomeIDLGHS3DPLUGIN.la \ + $(SMESH_LDFLAGS) -lSMESH \ + $(CAS_KERNEL) + +# resources files +nodist_salomeres_DATA= \ + GHS3DPlugin_images.qm \ + GHS3DPlugin_msg_en.qm diff --git a/src/Makefile.am b/src/Makefile.am index e7f6fea..043971b 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -27,6 +27,10 @@ include $(top_srcdir)/adm_local/unix/make_common_starter.am +if GHS3DPLUGIN_ENABLE_GUI + SUBDIRS = GUI +endif + # header files salomeinclude_HEADERS = @@ -36,24 +40,23 @@ lib_LTLIBRARIES = libGHS3DEngine.la dist_libGHS3DEngine_la_SOURCES = \ GHS3DPlugin_GHS3D.cxx \ GHS3DPlugin_GHS3D_i.cxx \ - GHS3DPlugin_i.cxx + GHS3DPlugin_i.cxx \ + GHS3DPlugin_Hypothesis.cxx \ + GHS3DPlugin_Hypothesis_i.cxx -libGHS3DEngine_la_CPPFLAGS = \ - $(KERNEL_CXXFLAGS) \ - $(GUI_CXXFLAGS) \ - $(GEOM_CXXFLAGS) \ - $(SMESH_CXXFLAGS) \ - $(BOOST_CPPFLAGS) \ - $(CORBA_CXXFLAGS) \ - $(CORBA_INCLUDES) \ - $(CAS_CPPFLAGS) \ +libGHS3DEngine_la_CPPFLAGS = \ + $(KERNEL_CXXFLAGS) \ + $(GEOM_CXXFLAGS) \ + $(MED_CXXFLAGS) \ + $(SMESH_CXXFLAGS) \ + $(BOOST_CPPFLAGS) \ + $(CORBA_CXXFLAGS) \ + $(CORBA_INCLUDES) \ + $(CAS_CPPFLAGS) \ -I$(top_builddir)/idl \ -I$(top_builddir)/salome_adm/unix libGHS3DEngine_la_LDFLAGS = \ ../idl/libSalomeIDLGHS3DPLUGIN.la \ - $(SMESH_LDFLAGS) -lSMESHimpl -lSMESHEngine \ + $(SMESH_LDFLAGS) -lSMESHimpl -lSMESHEngine $(KERNEL_LDFLAGS) -lSalomeGenericObj - -# resources files -nodist_salomeres_DATA = GHS3DPlugin_icons.qm