From: jfa Date: Tue, 21 Aug 2007 08:30:33 +0000 (+0000) Subject: Join modifications from V3_2_0_maintainance (V3_2_6pre4 - T32x_16Aug2007_16h00m) X-Git-Tag: V4_1_0a1~31 X-Git-Url: http://git.salome-platform.org/gitweb/?a=commitdiff_plain;h=856524def1094611dfd996d00a5226cee4b0c3cf;p=modules%2Fsmesh.git Join modifications from V3_2_0_maintainance (V3_2_6pre4 - T32x_16Aug2007_16h00m) --- diff --git a/adm_local/unix/config_files/check_SMESH.m4 b/adm_local/unix/config_files/check_SMESH.m4 index f1dbf22f1..5518cfa24 100644 --- a/adm_local/unix/config_files/check_SMESH.m4 +++ b/adm_local/unix/config_files/check_SMESH.m4 @@ -28,7 +28,9 @@ if test "x$SMESH_DIR" == "x" ; then else # search SMESH binaries in PATH variable - AC_PATH_PROG(TEMP, libSMESH_Swig.py) + #CCRTAC_PATH_PROG(TEMP, libSMESH_Swig.py) + #AC_PATH_PROG(TEMP, MED_Test) + AC_PATH_PROG(TEMP, smesh.py) if test "x$TEMP" != "x" ; then SMESH_BIN_DIR=`dirname $TEMP` SMESH_DIR=`dirname $SMESH_BIN_DIR` @@ -38,7 +40,9 @@ if test "x$SMESH_DIR" == "x" ; then # fi -if test -f ${SMESH_DIR}/bin/salome/libSMESH_Swig.py ; then +#CCRTif test -f ${SMESH_DIR}/bin/salome/libSMESH_Swig.py ; then +#if test -f ${SMESH_DIR}/bin/salome/MED_Test ; then +if test -f ${SMESH_DIR}/bin/salome/smesh.py ; then SMesh_ok=yes AC_MSG_RESULT(Using SMesh module distribution in ${SMESH_DIR}) diff --git a/build_configure b/build_configure index 7f3e6a42e..66f991e57 100755 --- a/build_configure +++ b/build_configure @@ -12,6 +12,7 @@ ORIG_DIR=`pwd` CONF_DIR=`echo $0 | sed -e "s,[^/]*$,,;s,/$,,;s,^$,.,"` +SMESH_WITH_GUI="yes" ######################################################################## # Test if the KERNEL_ROOT_DIR is set correctly @@ -28,12 +29,26 @@ fi # exit #fi +for option +do + case $option in + -with-ihm | --with-ihm) + SMESH_WITH_GUI="yes" + break;; + -without-ihm | --without-ihm | -with-ihm=no | --with-ihm=no) + SMESH_WITH_GUI="no" + break;; + esac +done + ######################################################################## # Test if the GUI_ROOT_DIR is set correctly -if test ! -d "${GUI_ROOT_DIR}"; then - echo "failed : GUI_ROOT_DIR variable is not correct !" - exit +if test ${SMESH_WITH_GUI} = yes; then + if test ! -d "${GUI_ROOT_DIR}"; then + echo "failed : GUI_ROOT_DIR variable is not correct !" + exit + fi fi ######################################################################## @@ -56,6 +71,11 @@ fi cd ${CONF_DIR} ABS_CONF_DIR=`pwd` +####################################################################### +# Update configure.ac script: to set SMESH_WITH_GUI variable +sed -e s/SMESH_WITH_GUI=[a-z]*/SMESH_WITH_GUI=${SMESH_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 @@ -84,11 +104,18 @@ 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 ${MED_ROOT_DIR}/adm_local/unix/config_files \ - -I ${GEOM_ROOT_DIR}/adm_local/unix/config_files || exit 1 +if test ${SMESH_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 || 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 || exit 1 +fi # ____________________________________________________________________ # libtoolize creates some configuration files (ltmain.sh, diff --git a/configure.ac b/configure.ac index b2799afe1..c267da8db 100644 --- a/configure.ac +++ b/configure.ac @@ -194,14 +194,22 @@ echo ENABLE_PTHREADS -if test "x${GUI_DISABLE_CORBA}" != "xyes" ; then echo echo --------------------------------------------- -echo testing omniORB +echo testing msg2qm echo --------------------------------------------- echo -CHECK_OMNIORB +CHECK_MSG2QM + +if test "x${GUI_DISABLE_CORBA}" != "xyes" ; then + echo + echo --------------------------------------------- + echo testing omniORB + echo --------------------------------------------- + echo + + CHECK_OMNIORB dnl echo dnl echo --------------------------------------------- @@ -211,58 +219,78 @@ dnl echo dnl CHECK_MICO -echo -echo --------------------------------------------- -echo default ORB : omniORB -echo --------------------------------------------- -echo + echo + echo --------------------------------------------- + echo default ORB : omniORB + echo --------------------------------------------- + echo -DEFAULT_ORB=omniORB + DEFAULT_ORB=omniORB -echo -echo --------------------------------------------- -echo testing Corba -echo --------------------------------------------- -echo + echo + echo --------------------------------------------- + echo testing Corba + echo --------------------------------------------- + echo -CHECK_CORBA + CHECK_CORBA -AC_SUBST_FILE(CORBA) -corba=make_$ORB -CORBA=adm_local/unix/$corba + AC_SUBST_FILE(CORBA) + corba=make_$ORB + CORBA=adm_local/unix/$corba fi -echo -echo --------------------------------------------- -echo testing openGL -echo --------------------------------------------- -echo -CHECK_OPENGL -echo -echo --------------------------------------------- -echo testing QT -echo --------------------------------------------- -echo +SMESH_WITH_GUI=yes -CHECK_QT +AM_CONDITIONAL(SMESH_ENABLE_GUI, [test "${SMESH_WITH_GUI}" = "yes"]) -echo -echo --------------------------------------------- -echo testing msg2qm -echo --------------------------------------------- -echo +if test "${SMESH_WITH_GUI}" = "yes"; then + echo + echo --------------------------------------------- + echo testing openGL + echo --------------------------------------------- + echo -CHECK_MSG2QM + CHECK_OPENGL -echo -echo --------------------------------------------- -echo testing VTK -echo --------------------------------------------- -echo + echo + echo --------------------------------------------- + echo testing QT + echo --------------------------------------------- + echo + + CHECK_QT -CHECK_VTK + 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 SMESH module necessary full GUI !" + exit + fi +fi echo echo --------------------------------------------- @@ -304,26 +332,6 @@ echo CHECK_HTML_GENERATORS -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 SMESH module necessary full GUI !" - exit -fi - echo echo --------------------------------------------- echo Testing Kernel @@ -458,6 +466,7 @@ AC_OUTPUT([ \ ./src/SMESHGUI/Makefile \ ./src/SMESH_I/Makefile \ ./src/SMESH_SWIG/Makefile \ + ./src/SMESH_SWIG_WITHIHM/Makefile \ ./src/StdMeshers/Makefile \ ./src/StdMeshersGUI/Makefile \ ./src/StdMeshers_I/Makefile \ diff --git a/idl/SMESH_Gen.idl b/idl/SMESH_Gen.idl index ba4d798d6..4f81e6e51 100644 --- a/idl/SMESH_Gen.idl +++ b/idl/SMESH_Gen.idl @@ -82,7 +82,6 @@ module SMESH interface SMESH_Gen : Engines::Component, SALOMEDS::Driver { - //GEOM::GEOM_Gen SetGeomEngine( in string containerLoc ); void SetGeomEngine( in GEOM::GEOM_Gen geomcompo ); diff --git a/resources/StdMeshers.xml b/resources/StdMeshers.xml index 9b1a1dfaf..70530de01 100644 --- a/resources/StdMeshers.xml +++ b/resources/StdMeshers.xml @@ -60,6 +60,7 @@ first; - switch(aGeom){ - case ePOINT1: - break; + switch(aGeom) { +// case ePOINT1: ## PAL16410 +// break; case ePOLYGONE: { PPolygoneInfo aPolygoneInfo = aMed->GetPPolygoneInfo(aMeshInfo,anEntity,aGeom); EBooleen anIsElemNum = takeNumbers ? aPolygoneInfo->IsElemNum() : eFAUX; @@ -345,6 +345,7 @@ DriverMED_R_SMESHDS_Mesh case ePENTA15: aNbNodes = 15; break; case eHEXA8: aNbNodes = 8; break; case eHEXA20: aNbNodes = 20; break; + case ePOINT1: aNbNodes = 1; break; default:; } vector aNodeIds(aNbNodes); @@ -378,14 +379,14 @@ DriverMED_R_SMESHDS_Mesh continue; bool isRenum = false; - SMDS_MeshElement* anElement = NULL; + const SMDS_MeshElement* anElement = NULL; TInt aFamNum = aCellInfo->GetFamNum(iElem); #ifndef _DEXCEPT_ try{ #endif //MESSAGE("Try to create element # " << iElem << " with id = " // << aCellInfo->GetElemNum(iElem)); - switch(aGeom){ + switch(aGeom) { case eSEG2: if(anIsElemNum) anElement = myMesh->AddEdgeWithID(aNodeIds[0], @@ -671,6 +672,10 @@ DriverMED_R_SMESHDS_Mesh isRenum = anIsElemNum; } break; + + case ePOINT1: + anElement = FindNode(myMesh,aNodeIds[0]); + break; } #ifndef _DEXCEPT_ }catch(const std::exception& exc){ diff --git a/src/DriverUNV/UNV2417_Structure.cxx b/src/DriverUNV/UNV2417_Structure.cxx index 67d2cbe25..a9da97d62 100644 --- a/src/DriverUNV/UNV2417_Structure.cxx +++ b/src/DriverUNV/UNV2417_Structure.cxx @@ -34,8 +34,9 @@ static int MYDEBUG = 0; #endif -static string _group_labels[] = {"2417", "2429", "2430", "2432", "2435", "2452", "2467"}; -#define NBGROUP 7 +static string _group_labels[] = {"2417", "2429", "2430", "2432", + "2435", "2452", "2467", "2477"}; +#define NBGROUP 8 static string _label_dataset = "2467"; @@ -98,7 +99,10 @@ void UNV2417::ReadGroup(const std::string& myGroupLabel, std::ifstream& in_strea for(int j=0; j < n_nodes; j++){ in_stream>>aElType; in_stream>>aElId; - if ((myGroupLabel.compare("2435") == 0) || (myGroupLabel.compare("2452") == 0) || (myGroupLabel.compare("2467") == 0)) { + if ((myGroupLabel.compare("2435") == 0) || + (myGroupLabel.compare("2452") == 0) || + (myGroupLabel.compare("2467") == 0) || + (myGroupLabel.compare("2477") == 0)) { in_stream>>aTmp; in_stream>>aTmp; } diff --git a/src/Makefile.am b/src/Makefile.am index 350144b07..941a72227 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -39,11 +39,16 @@ SUBDIRS = \ SMESH \ SMESH_I \ SMESHClient \ - OBJECT \ - SMESHFiltersSelection \ - SMESHGUI \ SMESH_SWIG \ MEFISTO2 \ StdMeshers \ - StdMeshers_I \ + StdMeshers_I + +if SMESH_ENABLE_GUI + SUBDIRS += \ + OBJECT \ + SMESHFiltersSelection \ + SMESHGUI \ + SMESH_SWIG_WITHIHM \ StdMeshersGUI +endif diff --git a/src/SMDS/SMDS_Mesh.cxx b/src/SMDS/SMDS_Mesh.cxx index bf40922dd..9c4838274 100644 --- a/src/SMDS/SMDS_Mesh.cxx +++ b/src/SMDS/SMDS_Mesh.cxx @@ -39,6 +39,37 @@ #include using namespace std; +#ifndef WIN32 +#include +#endif + +//================================================================================ +/*! + * \brief Raise an exception if free memory (ram+swap) too low + * \param doNotRaise - if true, suppres exception, just return bool + * \retval bool - true if there is enough memory + */ +//================================================================================ + +bool SMDS_Mesh::CheckMemory(const bool doNotRaise) throw (std::bad_alloc) +{ +#ifndef WIN32 + struct sysinfo si; + int err = sysinfo( &si ); + if ( err ) + return true; + + int freeMbyte = ( si.freeram + si.freeswap ) * si.mem_unit / 1024 / 1024; + if ( freeMbyte > 4 ) + return true; + if ( doNotRaise ) + return false; + throw std::bad_alloc(); +#else + return true; +#endif +} + /////////////////////////////////////////////////////////////////////////////// /// Create a new mesh object /////////////////////////////////////////////////////////////////////////////// @@ -96,6 +127,7 @@ SMDS_MeshNode * SMDS_Mesh::AddNodeWithID(double x, double y, double z, int ID) // find the MeshNode corresponding to ID const SMDS_MeshElement *node = myNodeIDFactory->MeshElement(ID); if(!node){ + CheckMemory(); SMDS_MeshNode * node=new SMDS_MeshNode(x, y, z); myNodes.Add(node); myNodeIDFactory->BindID(ID,node); @@ -143,6 +175,7 @@ SMDS_MeshEdge* SMDS_Mesh::AddEdgeWithID(const SMDS_MeshNode * n1, { if ( !n1 || !n2 ) return 0; + CheckMemory(); SMDS_MeshEdge * edge=new SMDS_MeshEdge(n1,n2); if(myElementIDFactory->BindID(ID, edge)) { SMDS_MeshNode *node1,*node2; @@ -280,6 +313,7 @@ SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshEdge * e1, return NULL; if ( !e1 || !e2 || !e3 ) return 0; + CheckMemory(); SMDS_MeshFace * face = new SMDS_FaceOfEdges(e1,e2,e3); myFaces.Add(face); @@ -318,6 +352,7 @@ SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshEdge * e1, if (!hasConstructionEdges()) return NULL; if ( !e1 || !e2 || !e3 || !e4 ) return 0; + CheckMemory(); SMDS_MeshFace * face = new SMDS_FaceOfEdges(e1,e2,e3,e4); myFaces.Add(face); @@ -381,6 +416,7 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1, { SMDS_MeshVolume* volume = 0; if ( !n1 || !n2 || !n3 || !n4) return volume; + CheckMemory(); if(hasConstructionFaces()) { SMDS_MeshFace * f1=FindFaceOrCreate(n1,n2,n3); SMDS_MeshFace * f2=FindFaceOrCreate(n1,n2,n4); @@ -464,6 +500,7 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1, { SMDS_MeshVolume* volume = 0; if ( !n1 || !n2 || !n3 || !n4 || !n5) return volume; + CheckMemory(); if(hasConstructionFaces()) { SMDS_MeshFace * f1=FindFaceOrCreate(n1,n2,n3,n4); SMDS_MeshFace * f2=FindFaceOrCreate(n1,n2,n5); @@ -551,6 +588,7 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1, { SMDS_MeshVolume* volume = 0; if ( !n1 || !n2 || !n3 || !n4 || !n5 || !n6) return volume; + CheckMemory(); if(hasConstructionFaces()) { SMDS_MeshFace * f1=FindFaceOrCreate(n1,n2,n3); SMDS_MeshFace * f2=FindFaceOrCreate(n4,n5,n6); @@ -650,6 +688,7 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1, { SMDS_MeshVolume* volume = 0; if ( !n1 || !n2 || !n3 || !n4 || !n5 || !n6 || !n7 || !n8) return volume; + CheckMemory(); if(hasConstructionFaces()) { SMDS_MeshFace * f1=FindFaceOrCreate(n1,n2,n3,n4); SMDS_MeshFace * f2=FindFaceOrCreate(n5,n6,n7,n8); @@ -707,6 +746,7 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshFace * f1, if (!hasConstructionFaces()) return NULL; if ( !f1 || !f2 || !f3 || !f4) return 0; + CheckMemory(); SMDS_MeshVolume * volume = new SMDS_VolumeOfFaces(f1,f2,f3,f4); myVolumes.Add(volume); @@ -749,6 +789,7 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshFace * f1, if (!hasConstructionFaces()) return NULL; if ( !f1 || !f2 || !f3 || !f4 || !f5) return 0; + CheckMemory(); SMDS_MeshVolume * volume = new SMDS_VolumeOfFaces(f1,f2,f3,f4,f5); myVolumes.Add(volume); @@ -793,6 +834,7 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshFace * f1, if (!hasConstructionFaces()) return NULL; if ( !f1 || !f2 || !f3 || !f4 || !f5 || !f6) return 0; + CheckMemory(); SMDS_MeshVolume * volume = new SMDS_VolumeOfFaces(f1,f2,f3,f4,f5,f6); myVolumes.Add(volume); @@ -829,6 +871,7 @@ SMDS_MeshFace* SMDS_Mesh::AddPolygonalFaceWithID { SMDS_MeshFace * face; + CheckMemory(); if (hasConstructionEdges()) { MESSAGE("Error : Not implemented"); @@ -892,6 +935,7 @@ SMDS_MeshVolume* SMDS_Mesh::AddPolyhedralVolumeWithID const int ID) { SMDS_MeshVolume* volume; + CheckMemory(); if (hasConstructionFaces()) { MESSAGE("Error : Not implemented"); return NULL; @@ -961,6 +1005,7 @@ SMDS_MeshFace * SMDS_Mesh::createTriangle(const SMDS_MeshNode * node1, const SMDS_MeshNode * node3) { if ( !node1 || !node2 || !node3) return 0; + CheckMemory(); if(hasConstructionEdges()) { SMDS_MeshEdge *edge1, *edge2, *edge3; @@ -990,6 +1035,7 @@ SMDS_MeshFace * SMDS_Mesh::createQuadrangle(const SMDS_MeshNode * node1, const SMDS_MeshNode * node4) { if ( !node1 || !node2 || !node3 || !node4 ) return 0; + CheckMemory(); if(hasConstructionEdges()) { SMDS_MeshEdge *edge1, *edge2, *edge3, *edge4; @@ -1290,6 +1336,7 @@ SMDS_MeshEdge* SMDS_Mesh::FindEdgeOrCreate(const SMDS_MeshNode * node1, SMDS_MeshEdge * toReturn=NULL; toReturn=const_cast(FindEdge(node1,node2)); if(toReturn==NULL) { + CheckMemory(); toReturn=new SMDS_MeshEdge(node1,node2); myEdges.Add(toReturn); } @@ -2996,4 +3043,3 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1, } return volume; } - diff --git a/src/SMDS/SMDS_Mesh.hxx b/src/SMDS/SMDS_Mesh.hxx index 2cdf3749b..1a1ef117e 100644 --- a/src/SMDS/SMDS_Mesh.hxx +++ b/src/SMDS/SMDS_Mesh.hxx @@ -482,6 +482,13 @@ public: const SMDS_MeshFace *FindFace(std::vector nodes_ids) const; static const SMDS_MeshFace* FindFace(std::vector nodes); + /*! + * \brief Raise an exception if free memory (ram+swap) too low + * \param doNotRaise - if true, suppres exception, just return bool + * \retval bool - true if there is enough memory + */ + static bool CheckMemory(const bool doNotRaise=false) throw (std::bad_alloc); + int MaxNodeID() const; int MinNodeID() const; int MaxElementID() const; diff --git a/src/SMDS/SMESH_SMDS.hxx b/src/SMDS/SMESH_SMDS.hxx index 207cf7210..d354e130e 100755 --- a/src/SMDS/SMESH_SMDS.hxx +++ b/src/SMDS/SMESH_SMDS.hxx @@ -36,4 +36,4 @@ #define SMDS_EXPORT #endif -#endif \ No newline at end of file +#endif diff --git a/src/SMESH/SMESH_Algo.hxx b/src/SMESH/SMESH_Algo.hxx index b27055c31..f08fd85e7 100644 --- a/src/SMESH/SMESH_Algo.hxx +++ b/src/SMESH/SMESH_Algo.hxx @@ -260,8 +260,14 @@ public: * \param E2 - the 2nd edge * \retval GeomAbs_Shape - regularity at the junction between E1 and E2 */ - static GeomAbs_Shape Continuity(const TopoDS_Edge & E1, - const TopoDS_Edge & E2); + static GeomAbs_Shape Continuity(const TopoDS_Edge & E1, const TopoDS_Edge & E2); + + /*! + * \brief Return true if an edge can be considered as a continuation of another + */ + static bool IsContinuous(const TopoDS_Edge & E1, const TopoDS_Edge & E2) { + return ( Continuity( E1, E2 ) >= GeomAbs_G1 ); + } /*! * \brief Return the node built on a vertex @@ -279,9 +285,10 @@ protected: */ bool error(int error, const SMESH_Comment& comment = ""); /*! - * \brief To be used as error in previous method + * \brief store COMPERR_ALGO_FAILED error and comment and then return false */ - SMESH_ComputeErrorName dfltErr() const { return COMPERR_ALGO_FAILED; } + bool error(const SMESH_Comment& comment = "") + { return error(COMPERR_ALGO_FAILED, comment); } /*! * \brief store error and return error->IsOK() */ diff --git a/src/SMESH/SMESH_Block.cxx b/src/SMESH/SMESH_Block.cxx index fa7fc282f..dfde6865a 100644 --- a/src/SMESH/SMESH_Block.cxx +++ b/src/SMESH/SMESH_Block.cxx @@ -30,6 +30,7 @@ #include #include #include +#include #include #include #include @@ -45,6 +46,8 @@ #include #include #include +#include +#include #include "SMDS_MeshNode.hxx" #include "SMDS_MeshVolume.hxx" @@ -55,7 +58,7 @@ using namespace std; -#define SQRT_FUNC 0 +//#define DEBUG_PARAM_COMPUTE //================================================================================ /*! @@ -381,24 +384,37 @@ bool SMESH_Block::ShellPoint(const gp_XYZ& theParams, const vector& p = thePointOnShape; thePoint = - x1 * p[ID_F0yz] + x * p[ID_F1yz] - + y1 * p[ID_Fx0z] + y * p[ID_Fx1z] - + z1 * p[ID_Fxy0] + z * p[ID_Fxy1] - + x1 * (y1 * (z1 * p[ID_V000] + z * p[ID_V001]) - + y * (z1 * p[ID_V010] + z * p[ID_V011])) - + x * (y1 * (z1 * p[ID_V100] + z * p[ID_V101]) - + y * (z1 * p[ID_V110] + z * p[ID_V111])); + x1 * p[ID_F0yz] + x * p[ID_F1yz] + + y1 * p[ID_Fx0z] + y * p[ID_Fx1z] + + z1 * p[ID_Fxy0] + z * p[ID_Fxy1] + + x1 * (y1 * (z1 * p[ID_V000] + z * p[ID_V001]) + + y * (z1 * p[ID_V010] + z * p[ID_V011])) + + x * (y1 * (z1 * p[ID_V100] + z * p[ID_V101]) + + y * (z1 * p[ID_V110] + z * p[ID_V111])); thePoint -= - x1 * (y1 * p[ID_E00z] + y * p[ID_E01z]) - + x * (y1 * p[ID_E10z] + y * p[ID_E11z]) - + y1 * (z1 * p[ID_Ex00] + z * p[ID_Ex01]) - + y * (z1 * p[ID_Ex10] + z * p[ID_Ex11]) - + z1 * (x1 * p[ID_E0y0] + x * p[ID_E1y0]) - + z * (x1 * p[ID_E0y1] + x * p[ID_E1y1]); + x1 * (y1 * p[ID_E00z] + y * p[ID_E01z]) + + x * (y1 * p[ID_E10z] + y * p[ID_E11z]) + + y1 * (z1 * p[ID_Ex00] + z * p[ID_Ex01]) + + y * (z1 * p[ID_Ex10] + z * p[ID_Ex11]) + + z1 * (x1 * p[ID_E0y0] + x * p[ID_E1y0]) + + z * (x1 * p[ID_E0y1] + x * p[ID_E1y1]); return true; } +//======================================================================= +//function : Constructor +//purpose : +//======================================================================= + +SMESH_Block::SMESH_Block(): + myNbIterations(0), + mySumDist(0.), + myTolerance(-1.) // to be re-initialized +{ +} + + //======================================================================= //function : NbVariables //purpose : @@ -428,12 +444,12 @@ Standard_Boolean SMESH_Block::Value(const math_Vector& theXYZ, math_Vector& theF { gp_XYZ P, params( theXYZ(1), theXYZ(2), theXYZ(3) ); if ( params.IsEqual( myParam, DBL_MIN )) { // same param - theFxyz( 1 ) = myValues[ 0 ]; + theFxyz( 1 ) = funcValue( myValues[ SQUARE_DIST ]); } else { ShellPoint( params, P ); gp_Vec dP( P - myPoint ); - theFxyz(1) = SQRT_FUNC ? dP.SquareMagnitude() : dP.Magnitude(); + theFxyz(1) = funcValue( dP.SquareMagnitude() ); } return true; } @@ -445,55 +461,60 @@ Standard_Boolean SMESH_Block::Value(const math_Vector& theXYZ, math_Vector& theF Standard_Boolean SMESH_Block::Derivatives(const math_Vector& XYZ,math_Matrix& Df) { - MESSAGE( "SMESH_Block::Derivatives()"); math_Vector F(1,3); return Values(XYZ,F,Df); } //======================================================================= -//function : Values +//function : GetStateNumber //purpose : //======================================================================= -//#define DEBUG_PARAM_COMPUTE +Standard_Integer SMESH_Block::GetStateNumber () +{ + return 0; //myValues[0] < 1e-1; +} + +//======================================================================= +//function : Values +//purpose : +//======================================================================= Standard_Boolean SMESH_Block::Values(const math_Vector& theXYZ, math_Vector& theFxyz, math_Matrix& theDf) { -// MESSAGE( endl<<"SMESH_Block::Values( "< myPoint), P is defined by the 2 other derivative direction -// int iPrev = ( iP ? iP - 1 : 2 ); -// int iNext = ( iP == 2 ? 0 : iP + 1 ); -// gp_Vec plnNorm = drv[ iPrev ].Crossed( drv [ iNext ] ); -// double Direc = plnNorm * drv[ iP ]; -// if ( Abs(Direc) <= DBL_MIN ) -// theDf( 1, iP + 1 ) = dP * drv[ iP ]; -// else { -// double Dis = plnNorm * P - plnNorm * myPoint; -// theDf( 1, iP + 1 ) = Dis/Direc; -// } +#else + // Distance from P to plane passing through myPoint and defined + // by the 2 other derivative directions: + // like IntAna_IntConicQuad::Perform (const gp_Lin& L, const gp_Pln& P) + // where L is (P -> myPoint), P is defined by the 2 other derivative direction + int iPrev = ( iP ? iP - 1 : 2 ); + int iNext = ( iP == 2 ? 0 : iP + 1 ); + gp_Vec plnNorm = drv[ iPrev ].Crossed( drv [ iNext ] ); + double Direc = plnNorm * drv[ iP ]; + if ( Abs(Direc) <= DBL_MIN ) + theDf( 1, iP + 1 ) = dP * drv[ iP ]; + else { + double Dis = plnNorm * P - plnNorm * myPoint; + theDf( 1, iP + 1 ) = Dis/Direc; + } +#endif } #ifdef DEBUG_PARAM_COMPUTE cout << "F = " << theFxyz(1) << " DRV: " << theDf(1,1) << " " << theDf(1,2) << " " << theDf(1,3) << endl; + myNbIterations +=3; // how many times call ShellPoint() #endif - //myNbIterations +=3; // how many time call ShellPoint() // store better values - myParam = params; - myValues[0]= theFxyz(1); - myValues[1]= theDf(1,1); - myValues[2]= theDf(1,2); - myValues[3]= theDf(1,3); - -// SCRUTE( theFxyz(1) ); -// SCRUTE( theDf( 1,1 )); -// SCRUTE( theDf( 1,2 )); -// SCRUTE( theDf( 1,3 )); + myParam = params; + myValues[SQUARE_DIST]= sqDist; + myValues[DRV_1] = theDf(1,DRV_1); + myValues[DRV_2] = theDf(1,DRV_2); + myValues[DRV_3] = theDf(1,DRV_3); } return true; } +//============================================================================ +//function : computeParameters +//purpose : compute point parameters in the block using math_FunctionSetRoot +//============================================================================ + +bool SMESH_Block::computeParameters(const gp_Pnt& thePoint, + gp_XYZ& theParams, + const gp_XYZ& theParamsHint) +{ + myPoint = thePoint.XYZ(); + + myParam.SetCoord( -1,-1,-1 ); + myValues[ SQUARE_DIST ] = 1e100; + + math_Vector low ( 1, 3, 0.0 ); + math_Vector up ( 1, 3, 1.0 ); + math_Vector tol ( 1, 3, 1e-4 ); + math_Vector start( 1, 3, 0.0 ); + start( 1 ) = theParamsHint.X(); + start( 2 ) = theParamsHint.Y(); + start( 3 ) = theParamsHint.Z(); + + math_FunctionSetRoot paramSearch( *this, tol ); + + mySquareFunc = 0; // large approaching steps + //if ( hasHint ) mySquareFunc = 1; // small approaching steps + + double loopTol = 10 * myTolerance; + int nbLoops = 0; + while ( distance() > loopTol && nbLoops <= 3 ) + { + paramSearch.Perform ( *static_cast(this), + start, low, up ); + start( 1 ) = myParam.X(); + start( 2 ) = myParam.Y(); + start( 3 ) = myParam.Z(); + mySquareFunc = !mySquareFunc; + nbLoops++; + } +#ifdef DEBUG_PARAM_COMPUTE + mySumDist += distance(); + cout << " ------ SOLUTION: ( "<< myParam.X() <<" "<< myParam.Y() <<" "<< myParam.Z() <<" )"< 0 ) + theParams.SetCoord( myFaceIndex, myFaceParam ); + + return true; +} + //======================================================================= //function : ComputeParameters //purpose : compute point parameters in the block @@ -558,7 +631,8 @@ Standard_Boolean SMESH_Block::Values(const math_Vector& theXYZ, bool SMESH_Block::ComputeParameters(const gp_Pnt& thePoint, gp_XYZ& theParams, - const int theShapeID) + const int theShapeID, + const gp_XYZ& theParamsHint) { if ( VertexParameters( theShapeID, theParams )) return true; @@ -575,19 +649,17 @@ bool SMESH_Block::ComputeParameters(const gp_Pnt& thePoint, return false; } -// MESSAGE( endl<<"SMESH_Block::ComputeParameters( " -// <X(); - start( 2 ) = bestParam->Y(); - start( 3 ) = bestParam->Z(); + start = *bestParam; } - myFaceIndex = -1; + int myFaceIndex = -1; + double myFaceParam = 0.; if ( isOnFace ) { // put a point on the face for ( int iCoord = 0; iCoord < 3; iCoord++ ) if ( coef[ iCoord ] ) { - myFaceIndex = iCoord; - myFaceParam = ( coef[ myFaceIndex ] < 0.5 ) ? 0.0 : 1.0; - start( iCoord + 1 ) = myFaceParam; + myFaceIndex = iCoord + 1; + myFaceParam = ( coef[ iCoord ] < 0.5 ) ? 0.0 : 1.0; + start.SetCoord( myFaceIndex, myFaceParam ); } } - math_Vector low ( 1, 3, 0.0 ); - math_Vector up ( 1, 3, 1.0 ); - math_Vector tol ( 1, 3, 1e-4 ); - math_FunctionSetRoot paramSearch( *this, tol ); #ifdef DEBUG_PARAM_COMPUTE cout << " #### POINT " < 1e-1 && nbLoops++ < 10 ) { - paramSearch.Perform ( *static_cast(this), - start, low, up ); - if ( !paramSearch.IsDone() ) { - //MESSAGE( " !paramSearch.IsDone() " ); + + if ( myTolerance < 0 ) myTolerance = 1e-6; + + const double parDelta = 1e-4; + const double sqTolerance = myTolerance * myTolerance; + + gp_XYZ solution = start, params = start; + double sqDistance = 1e100; + int nbLoops = 0, nbGetWorst = 0; + + while ( nbLoops <= 100 ) + { + gp_XYZ P, Pi; + ShellPoint( params, P ); + + gp_Vec dP( thePoint, P ); + double sqDist = dP.SquareMagnitude(); + + if ( sqDist > sqDistance ) { // solution get worse + if ( ++nbGetWorst > 2 ) + return computeParameters( thePoint, theParams, solution ); } - else { - //MESSAGE( " NB ITERATIONS: " << paramSearch.NbIterations() ); +#ifdef DEBUG_PARAM_COMPUTE + cout << "PARAMS: ( " << params.X() <<" "<< params.Y() <<" "<< params.Z() <<" )"<< endl; + cout << "DIST: " << sqrt( sqDist ) << endl; +#endif + + if ( sqDist < sqDistance ) { // get better + sqDistance = sqDist; + solution = params; + nbGetWorst = 0; + if ( sqDistance < sqTolerance ) // a solution found + break; } - start( 1 ) = myParam.X(); - start( 2 ) = myParam.Y(); - start( 3 ) = myParam.Z(); - //MESSAGE( "Distance: " << ( SQRT_FUNC ? sqrt(myValues[0]) : myValues[0] )); + + // look for a next better solution + for ( int iP = 1; iP <= 3; iP++ ) { + if ( iP == myFaceIndex ) + continue; + // see where we move with a small (=parDelta) step in this direction + gp_XYZ nearParams = params; + bool onEdge = ( params.Coord( iP ) + parDelta > 1. ); + if ( onEdge ) + nearParams.SetCoord( iP, params.Coord( iP ) - parDelta ); + else + nearParams.SetCoord( iP, params.Coord( iP ) + parDelta ); + ShellPoint( nearParams, Pi ); + gp_Vec dPi ( P, Pi ); + if ( onEdge ) dPi *= -1.; + // modify a parameter + double mag = dPi.Magnitude(); + if ( mag < DBL_MIN ) + continue; + gp_Vec dir = dPi / mag; // dir we move modifying the parameter + double dist = dir * dP; // where we should get to + double dPar = dist / mag * parDelta; // predict parameter change + double curPar = params.Coord( iP ); + double par = curPar - dPar; // new parameter value + while ( par > 1 || par < 0 ) { + dPar /= 2.; + par = curPar - dPar; + } + params.SetCoord( iP, par ); + } + + nbLoops++; } #ifdef DEBUG_PARAM_COMPUTE - cout << "-------SOLUTION-------: " << endl - << myParam.X() << " " << myParam.Y() << " " << myParam.Z() << endl - << " ------ DIST :" << myValues[0] << endl; + myNbIterations += nbLoops*4; // how many times ShellPoint called + mySumDist += sqrt( sqDistance ); + cout << " ------ SOLUTION: ( "<= 0 ) - myParam.SetCoord( myFaceIndex + 1, myFaceParam ); + theParams = solution; - theParams = myParam; + if ( myFaceIndex > 0 ) + theParams.SetCoord( myFaceIndex, myFaceParam ); return true; } @@ -734,18 +860,6 @@ bool SMESH_Block::EdgeParameters(const int theEdgeID, const double theU, gp_XYZ& return false; } -//======================================================================= -//function : GetStateNumber -//purpose : -//======================================================================= - -Standard_Integer SMESH_Block::GetStateNumber () -{ -// MESSAGE( endl<<"SMESH_Block::GetStateNumber( "< edgeIdVec(4, -1); GetFaceEdgesIDs( iF, edgeIdVec ); - tFace.Set( iF, myEdge[ edgeIdVec [ 0 ]], myEdge[ edgeIdVec [ 1 ]]); + tFace.Set( iF, myEdge[ edgeIdVec [ 0 ] - ID_Ex00], myEdge[ edgeIdVec [ 1 ] - ID_Ex00]); } return true; @@ -1593,4 +1707,3 @@ void SMESH_Block::GetEdgeVertexIDs (const int edgeID, vector< int >& vertexVec ) MESSAGE(" GetEdgeVertexIDs(), wrong edge ID: " << edgeID ); } } - diff --git a/src/SMESH/SMESH_Block.hxx b/src/SMESH/SMESH_Block.hxx index 392160279..c5bbc1e2f 100644 --- a/src/SMESH/SMESH_Block.hxx +++ b/src/SMESH/SMESH_Block.hxx @@ -27,22 +27,19 @@ #include "SMESH_SMESH.hxx" -#include -#include -#include +//#include +//#include +//#include + #include #include #include #include #include #include -#include -#include #include #include #include -#include -#include #include #include @@ -53,6 +50,7 @@ class SMDS_MeshNode; class Adaptor3d_Surface; class Adaptor2d_Curve2d; class Adaptor3d_Curve; +class gp_Pnt; // ========================================================= // class calculating coordinates of 3D points by normalized @@ -147,7 +145,7 @@ class SMESH_EXPORT SMESH_Block: public math_FunctionSetWithDerivatives // Initialization // --------------- - SMESH_Block (): myNbIterations(0), mySumDist(0.) {} + SMESH_Block(); bool LoadBlockShapes(const TopoDS_Shell& theShell, const TopoDS_Vertex& theVertex000, @@ -242,7 +240,8 @@ public: bool ComputeParameters (const gp_Pnt& thePoint, gp_XYZ& theParams, - const int theShapeID = ID_Shell); + const int theShapeID = ID_Shell, + const gp_XYZ& theParamsHint = gp_XYZ(-1,-1,-1)); // compute point parameters in the block. // Note: for edges, it is better to use EdgeParameters() @@ -362,14 +361,21 @@ public: // for param computation + enum { SQUARE_DIST = 0, DRV_1, DRV_2, DRV_3 }; + double distance () const { return sqrt( myValues[ SQUARE_DIST ]); } + double funcValue(double sqDist) const { return mySquareFunc ? sqDist : sqrt(sqDist); } + bool computeParameters(const gp_Pnt& thePoint, gp_XYZ& theParams, const gp_XYZ& theParamsHint); + int myFaceIndex; double myFaceParam; int myNbIterations; double mySumDist; + double myTolerance; + bool mySquareFunc; gp_XYZ myPoint; // the given point gp_XYZ myParam; // the best parameters guess - double myValues[ 4 ]; // values computed at myParam: function value and 3 derivatives + double myValues[ 4 ]; // values computed at myParam: square distance and 3 derivatives typedef pair TxyzPair; TxyzPair my3x3x3GridNodes[ 27 ]; // to compute the first param guess diff --git a/src/SMESH/SMESH_Gen.cxx b/src/SMESH/SMESH_Gen.cxx index 3c34f2e63..f3f25d9e2 100644 --- a/src/SMESH/SMESH_Gen.cxx +++ b/src/SMESH/SMESH_Gen.cxx @@ -322,7 +322,11 @@ static bool checkMissing(SMESH_Gen* aGen, if ( status == SMESH_Hypothesis::HYP_BAD_PARAMETER ) { INFOS( "ERROR: hypothesis of " << (IsGlobalHypothesis ? "Global " : "Local ") << "<" << algo->GetName() << "> has a bad parameter value"); - errName = SMESH_Hypothesis::HYP_BAD_PARAMETER; + errName = status; + } else if ( status == SMESH_Hypothesis::HYP_BAD_GEOMETRY ) { + INFOS( "ERROR: " << (IsGlobalHypothesis ? "Global " : "Local ") + << "<" << algo->GetName() << "> assigned to mismatching geometry"); + errName = status; } else { INFOS( "ERROR: " << (IsGlobalHypothesis ? "Global " : "Local ") << "<" << algo->GetName() << "> misses some hypothesis"); diff --git a/src/SMESH/SMESH_HypoFilter.hxx b/src/SMESH/SMESH_HypoFilter.hxx index ca883167e..041166d41 100644 --- a/src/SMESH/SMESH_HypoFilter.hxx +++ b/src/SMESH/SMESH_HypoFilter.hxx @@ -78,9 +78,15 @@ class SMESH_EXPORT SMESH_HypoFilter: public SMESH_HypoPredicate static SMESH_HypoPredicate* HasDim(const int theDim); static SMESH_HypoPredicate* HasType(const int theHypType); + /*! + * \brief check aHyp or/and aShape it is assigned to + */ bool IsOk (const SMESH_Hypothesis* aHyp, const TopoDS_Shape& aShape) const; - // check aHyp or/and aShape it is assigned to + /*! + * \brief return true if contains no predicates + */ + bool IsAny() const { return myPredicates.empty(); } ~SMESH_HypoFilter(); diff --git a/src/SMESH/SMESH_Mesh.cxx b/src/SMESH/SMESH_Mesh.cxx index 0f464bf0f..a2a4dcbb5 100644 --- a/src/SMESH/SMESH_Mesh.cxx +++ b/src/SMESH/SMESH_Mesh.cxx @@ -153,7 +153,6 @@ void SMESH_Mesh::ShapeToMesh(const TopoDS_Shape & aShape) i_gr++; } _mapAncestors.Clear(); - _mapPropagationChains.Clear(); // clear SMESHDS TopoDS_Shape aNullShape; @@ -363,6 +362,10 @@ SMESH_Hypothesis::Hypothesis_Status if ( ret < aBestRet ) aBestRet = ret; } + // bind hypotheses to a group just to know + SMESH_Hypothesis *anHyp = _gen->GetStudyContext(_studyId)->mapHypothesis[anHypId]; + GetMeshDS()->AddHypothesis( aSubShape, anHyp ); + if ( SMESH_Hypothesis::IsStatusFatal( aBestRet )) return aBestRet; return aWorstNotFatal; @@ -466,6 +469,9 @@ SMESH_Hypothesis::Hypothesis_Status if ( ret < aBestRet ) aBestRet = ret; } + SMESH_Hypothesis *anHyp = _gen->GetStudyContext(_studyId)->mapHypothesis[anHypId]; + GetMeshDS()->RemoveHypothesis( aSubShape, anHyp ); + if ( SMESH_Hypothesis::IsStatusFatal( aBestRet )) return aBestRet; return aWorstNotFatal; @@ -859,9 +865,6 @@ void SMESH_Mesh::NotifySubMeshesHypothesisModification(const SMESH_Hypothesis* h { aSubMesh->AlgoStateEngine(SMESH_subMesh::MODIF_HYP, const_cast< SMESH_Hypothesis*>( hyp )); - - if ( algo->GetDim() == 1 && IsPropagationHypothesis( aSubShape )) - CleanMeshOnPropagationChain( aSubShape ); } } } @@ -1289,279 +1292,6 @@ void SMESH_Mesh::RemoveGroup (const int theGroupID) _mapGroup.erase (theGroupID); } -//============================================================================= -/*! - * IsLocal1DHypothesis - * Returns a local 1D hypothesis used for theEdge - */ -//============================================================================= -const SMESH_Hypothesis* SMESH_Mesh::IsLocal1DHypothesis (const TopoDS_Shape& theEdge) -{ - SMESH_HypoFilter hypo ( SMESH_HypoFilter::HasDim( 1 )); - hypo.AndNot( hypo.IsAlgo() ).AndNot( hypo.IsAssignedTo( GetMeshDS()->ShapeToMesh() )); - - return GetHypothesis( theEdge, hypo, true ); -} - -//============================================================================= -/*! - * IsPropagationHypothesis - */ -//============================================================================= -bool SMESH_Mesh::IsPropagationHypothesis (const TopoDS_Shape& theEdge) -{ - return _mapPropagationChains.Contains(theEdge); -} - -//============================================================================= -/*! - * IsPropagatedHypothesis - */ -//============================================================================= -bool SMESH_Mesh::IsPropagatedHypothesis (const TopoDS_Shape& theEdge, - TopoDS_Shape& theMainEdge) -{ - int nbChains = _mapPropagationChains.Extent(); - for (int i = 1; i <= nbChains; i++) { - //const TopTools_IndexedMapOfShape& aChain = _mapPropagationChains.FindFromIndex(i); - const SMESH_IndexedMapOfShape& aChain = _mapPropagationChains.FindFromIndex(i); - if (aChain.Contains(theEdge)) { - theMainEdge = _mapPropagationChains.FindKey(i); - return true; - } - } - - return false; -} -//============================================================================= -/*! - * IsReversedInChain - */ -//============================================================================= - -bool SMESH_Mesh::IsReversedInChain (const TopoDS_Shape& theEdge, - const TopoDS_Shape& theMainEdge) -{ - if ( !theMainEdge.IsNull() && !theEdge.IsNull() && - _mapPropagationChains.Contains( theMainEdge )) - { - const SMESH_IndexedMapOfShape& aChain = - _mapPropagationChains.FindFromKey( theMainEdge ); - int index = aChain.FindIndex( theEdge ); - if ( index ) - return aChain(index).Orientation() == TopAbs_REVERSED; - } - return false; -} - -//============================================================================= -/*! - * CleanMeshOnPropagationChain - */ -//============================================================================= -void SMESH_Mesh::CleanMeshOnPropagationChain (const TopoDS_Shape& theMainEdge) -{ - const SMESH_IndexedMapOfShape& aChain = _mapPropagationChains.FindFromKey(theMainEdge); - int i, nbEdges = aChain.Extent(); - for (i = 1; i <= nbEdges; i++) { - TopoDS_Shape anEdge = aChain.FindKey(i); - SMESH_subMesh *subMesh = GetSubMesh(anEdge); - SMESHDS_SubMesh *subMeshDS = subMesh->GetSubMeshDS(); - if (subMeshDS && subMeshDS->NbElements() > 0) { - subMesh->ComputeStateEngine(SMESH_subMesh::CLEAN); - } - } -} - -//============================================================================= -/*! - * RebuildPropagationChains - * Rebuild all existing propagation chains. - * Have to be used, if 1D hypothesis have been assigned/removed to/from any edge - */ -//============================================================================= -bool SMESH_Mesh::RebuildPropagationChains() -{ - bool ret = true; - - // Clean all chains, because they can be not up-to-date - int i, nbChains = _mapPropagationChains.Extent(); - for (i = 1; i <= nbChains; i++) { - TopoDS_Shape aMainEdge = _mapPropagationChains.FindKey(i); - CleanMeshOnPropagationChain(aMainEdge); - _mapPropagationChains.ChangeFromIndex(i).Clear(); - } - - // Build all chains - for (i = 1; i <= nbChains; i++) { - TopoDS_Shape aMainEdge = _mapPropagationChains.FindKey(i); - if (!BuildPropagationChain(aMainEdge)) - ret = false; - CleanMeshOnPropagationChain(aMainEdge); - } - - return ret; -} - -//============================================================================= -/*! - * RemovePropagationChain - * Have to be used, if Propagation hypothesis is removed from - */ -//============================================================================= -bool SMESH_Mesh::RemovePropagationChain (const TopoDS_Shape& theMainEdge) -{ - if (!_mapPropagationChains.Contains(theMainEdge)) - return false; - - // Clean mesh elements and nodes, built on the chain - CleanMeshOnPropagationChain(theMainEdge); - - // Clean the chain - _mapPropagationChains.ChangeFromKey(theMainEdge).Clear(); - - // Remove the chain from the map - int i = _mapPropagationChains.FindIndex(theMainEdge); - if ( i == _mapPropagationChains.Extent() ) - _mapPropagationChains.RemoveLast(); - else { - TopoDS_Vertex anEmptyShape; - BRep_Builder BB; - BB.MakeVertex(anEmptyShape, gp_Pnt(0,0,0), 0.1); - SMESH_IndexedMapOfShape anEmptyMap; - _mapPropagationChains.Substitute(i, anEmptyShape, anEmptyMap); - } - - return true; -} - -//============================================================================= -/*! - * BuildPropagationChain - */ -//============================================================================= -bool SMESH_Mesh::BuildPropagationChain (const TopoDS_Shape& theMainEdge) -{ - if (theMainEdge.ShapeType() != TopAbs_EDGE) return true; - - // Add new chain, if there is no - if (!_mapPropagationChains.Contains(theMainEdge)) { - SMESH_IndexedMapOfShape aNewChain; - _mapPropagationChains.Add(theMainEdge, aNewChain); - } - - // Check presence of 1D hypothesis to be propagated - const SMESH_Hypothesis* aMainHyp = IsLocal1DHypothesis(theMainEdge); - if (!aMainHyp) { - MESSAGE("Warning: There is no 1D hypothesis to propagate. Please, assign."); - return true; - } - - // Edges, on which the 1D hypothesis will be propagated from - SMESH_IndexedMapOfShape& aChain = _mapPropagationChains.ChangeFromKey(theMainEdge); - if (aChain.Extent() > 0) { - CleanMeshOnPropagationChain(theMainEdge); - aChain.Clear(); - } - - // At first put in the chain - aChain.Add(theMainEdge); - - // List of edges, added to chain on the previous cycle pass - TopTools_ListOfShape listPrevEdges; - listPrevEdges.Append(theMainEdge.Oriented( TopAbs_FORWARD )); - -// 5____4____3____4____5____6 -// | | | | | | -// | | | | | | -// 4____3____2____3____4____5 -// | | | | | | Number in the each knot of -// | | | | | | grid indicates cycle pass, -// 3____2____1____2____3____4 on which corresponding edge -// | | | | | | (perpendicular to the plane -// | | | | | | of view) will be found. -// 2____1____0____1____2____3 -// | | | | | | -// | | | | | | -// 3____2____1____2____3____4 - - // Collect all edges pass by pass - while (listPrevEdges.Extent() > 0) { - // List of edges, added to chain on this cycle pass - TopTools_ListOfShape listCurEdges; - - // Find the next portion of edges - TopTools_ListIteratorOfListOfShape itE (listPrevEdges); - for (; itE.More(); itE.Next()) { - TopoDS_Shape anE = itE.Value(); - - // Iterate on faces, having edge - TopTools_ListIteratorOfListOfShape itA (GetAncestors(anE)); - for (; itA.More(); itA.Next()) { - TopoDS_Shape aW = itA.Value(); - - // There are objects of different type among the ancestors of edge - if (aW.ShapeType() == TopAbs_WIRE) { - TopoDS_Shape anOppE; - - BRepTools_WireExplorer aWE (TopoDS::Wire(aW)); - Standard_Integer nb = 1, found = 0; - TopTools_Array1OfShape anEdges (1,4); - for (; aWE.More(); aWE.Next(), nb++) { - if (nb > 4) { - found = 0; - break; - } - anEdges(nb) = aWE.Current(); - if (!_mapAncestors.Contains(anEdges(nb))) { - MESSAGE("WIRE EXPLORER HAVE GIVEN AN INVALID EDGE !!!"); - break; - } - if (anEdges(nb).IsSame(anE)) found = nb; - } - - if (nb == 5 && found > 0) { - // Quadrangle face found, get an opposite edge - Standard_Integer opp = found + 2; - if (opp > 4) opp -= 4; - anOppE = anEdges(opp); - - // add anOppE to aChain if ... - if (!aChain.Contains(anOppE)) { // ... anOppE is not in aChain - if (!IsLocal1DHypothesis(anOppE)) { // ... no other 1d hyp on anOppE - TopoDS_Shape aMainEdgeForOppEdge; // ... no other hyp is propagated to anOppE - if (!IsPropagatedHypothesis(anOppE, aMainEdgeForOppEdge)) - { - // Add found edge to the chain oriented so that to - // have it co-directed with a forward MainEdge - TopAbs_Orientation ori = anE.Orientation(); - if ( anEdges(opp).Orientation() == anEdges(found).Orientation() ) - ori = TopAbs::Reverse( ori ); - anOppE.Orientation( ori ); - aChain.Add(anOppE); - listCurEdges.Append(anOppE); - } - else { - // Collision! - MESSAGE("Error: Collision between propagated hypotheses"); - CleanMeshOnPropagationChain(theMainEdge); - aChain.Clear(); - return ( aMainHyp == IsLocal1DHypothesis(aMainEdgeForOppEdge) ); - } - } - } - } // if (nb == 5 && found > 0) - } // if (aF.ShapeType() == TopAbs_WIRE) - } // for (; itF.More(); itF.Next()) - } // for (; itE.More(); itE.Next()) - - listPrevEdges = listCurEdges; - } // while (listPrevEdges.Extent() > 0) - - CleanMeshOnPropagationChain(theMainEdge); - return true; -} - //======================================================================= //function : GetAncestors //purpose : return list of ancestors of theSubShape in the order @@ -1581,6 +1311,7 @@ const TopTools_ListOfShape& SMESH_Mesh::GetAncestors(const TopoDS_Shape& theS) c //function : Dump //purpose : dumps contents of mesh to stream [ debug purposes ] //======================================================================= + ostream& SMESH_Mesh::Dump(ostream& save) { int clause = 0; @@ -1653,6 +1384,7 @@ ostream& SMESH_Mesh::Dump(ostream& save) //function : GetElementType //purpose : Returns type of mesh element with certain id //======================================================================= + SMDSAbs_ElementType SMESH_Mesh::GetElementType( const int id, const bool iselem ) { return _myMeshDS->GetElementType( id, iselem ); diff --git a/src/SMESH/SMESH_Mesh.hxx b/src/SMESH/SMESH_Mesh.hxx index d9538fe86..ba122d08b 100644 --- a/src/SMESH/SMESH_Mesh.hxx +++ b/src/SMESH/SMESH_Mesh.hxx @@ -237,30 +237,7 @@ public: void RemoveGroup (const int theGroupID); - // Propagation hypothesis management - - const SMESH_Hypothesis* IsLocal1DHypothesis (const TopoDS_Shape& theEdge); - // Returns a local 1D hypothesis used for theEdge. - - bool IsPropagationHypothesis (const TopoDS_Shape& theEdge); - // Returns true, if a local Propagation hypothesis is set directly on - - bool IsPropagatedHypothesis (const TopoDS_Shape& theEdge, - TopoDS_Shape& theMainEdge); - // Returns true, if a local 1D hypothesis is - // propagated on from some other edge. - // Returns through the edge, from - // which the 1D hypothesis is propagated on - - bool IsReversedInChain (const TopoDS_Shape& theEdge, - const TopoDS_Shape& theMainEdge); - // Returns true if theEdge should be reversed to be - // co-directed with theMainEdge - - bool RebuildPropagationChains(); - bool RemovePropagationChain (const TopoDS_Shape& theMainEdge); - bool BuildPropagationChain (const TopoDS_Shape& theMainEdge); - + SMDSAbs_ElementType GetElementType( const int id, const bool iselem ); // @@ -268,9 +245,6 @@ public: ostream& Dump(ostream & save); private: - // Propagation hypothesis management - void CleanMeshOnPropagationChain(const TopoDS_Shape& theMainEdge); - // protected: int _id; // id given by creator (unique within the creator instance) @@ -287,8 +261,6 @@ protected: TopTools_IndexedDataMapOfShapeListOfShape _mapAncestors; - IndexedMapOfChain _mapPropagationChains; // Propagation hypothesis management - protected: SMESH_Mesh() {}; SMESH_Mesh(const SMESH_Mesh&) {}; diff --git a/src/SMESH/SMESH_MeshEditor.cxx b/src/SMESH/SMESH_MeshEditor.cxx index 5ff5f6d17..8c2eec106 100644 --- a/src/SMESH/SMESH_MeshEditor.cxx +++ b/src/SMESH/SMESH_MeshEditor.cxx @@ -269,18 +269,26 @@ bool SMESH_MeshEditor::Remove (const list< int >& theIDs, if ( !elem ) continue; - // Find sub-meshes to notify about modification - SMDS_ElemIteratorPtr nodeIt = elem->nodesIterator(); - while ( nodeIt->more() ) { - const SMDS_MeshNode* node = static_cast( nodeIt->next() ); - const SMDS_PositionPtr& aPosition = node->GetPosition(); - if ( aPosition.get() ) { - if ( int aShapeID = aPosition->GetShapeId() ) { + // Notify VERTEX sub-meshes about modification + if ( isNodes ) { + const SMDS_MeshNode* node = cast2Node( elem ); + if ( node->GetPosition()->GetTypeOfPosition() == SMDS_TOP_VERTEX ) + if ( int aShapeID = node->GetPosition()->GetShapeId() ) if ( SMESH_subMesh * sm = GetMesh()->GetSubMeshContaining( aShapeID ) ) smmap.insert( sm ); - } - } } + // Find sub-meshes to notify about modification +// SMDS_ElemIteratorPtr nodeIt = elem->nodesIterator(); +// while ( nodeIt->more() ) { +// const SMDS_MeshNode* node = static_cast( nodeIt->next() ); +// const SMDS_PositionPtr& aPosition = node->GetPosition(); +// if ( aPosition.get() ) { +// if ( int aShapeID = aPosition->GetShapeId() ) { +// if ( SMESH_subMesh * sm = GetMesh()->GetSubMeshContaining( aShapeID ) ) +// smmap.insert( sm ); +// } +// } +// } // Do remove if ( isNodes ) @@ -296,9 +304,9 @@ bool SMESH_MeshEditor::Remove (const list< int >& theIDs, (*smIt)->ComputeStateEngine( SMESH_subMesh::MESH_ENTITY_REMOVED ); } - // Check if the whole mesh becomes empty - if ( SMESH_subMesh * sm = GetMesh()->GetSubMeshContaining( 1 ) ) - sm->ComputeStateEngine( SMESH_subMesh::CHECK_COMPUTE_STATE ); +// // Check if the whole mesh becomes empty +// if ( SMESH_subMesh * sm = GetMesh()->GetSubMeshContaining( 1 ) ) +// sm->ComputeStateEngine( SMESH_subMesh::CHECK_COMPUTE_STATE ); return true; } @@ -5729,7 +5737,7 @@ SMESH_MeshEditor::Sew_Error { nodeGroupsToMerge.push_back( list() ); nodeGroupsToMerge.back().push_back( *nIt[1] ); // to keep - nodeGroupsToMerge.back().push_back( *nIt[0] ); // tp remove + nodeGroupsToMerge.back().push_back( *nIt[0] ); // to remove } } else { @@ -7249,7 +7257,9 @@ SMESH_MeshEditor::Sew_Error */ //================================================================================ +#ifdef _DEBUG_ //#define DEBUG_MATCHING_NODES +#endif SMESH_MeshEditor::Sew_Error SMESH_MeshEditor::FindMatchingNodes(set& theSide1, diff --git a/src/SMESH/SMESH_MesherHelper.cxx b/src/SMESH/SMESH_MesherHelper.cxx index 6afe18300..024a93e5d 100644 --- a/src/SMESH/SMESH_MesherHelper.cxx +++ b/src/SMESH/SMESH_MesherHelper.cxx @@ -73,6 +73,7 @@ bool SMESH_MesherHelper::IsQuadraticSubMesh(const TopoDS_Shape& aSh) // also we have to fill myNLinkNodeMap myCreateQuadratic = true; mySeamShapeIds.clear(); + myDegenShapeIds.clear(); TopAbs_ShapeEnum subType( aSh.ShapeType()==TopAbs_FACE ? TopAbs_EDGE : TopAbs_FACE ); SMDSAbs_ElementType elemType( subType==TopAbs_FACE ? SMDSAbs_Face : SMDSAbs_Edge ); @@ -150,6 +151,7 @@ void SMESH_MesherHelper::SetSubShape(const TopoDS_Shape& aSh) myShape = aSh; mySeamShapeIds.clear(); + myDegenShapeIds.clear(); if ( myShape.IsNull() ) { myShapeID = -1; @@ -165,8 +167,9 @@ void SMESH_MesherHelper::SetSubShape(const TopoDS_Shape& aSh) BRepAdaptor_Surface surface( face ); if ( surface.IsUPeriodic() || surface.IsVPeriodic() ) { - // look for a seam edge - for ( TopExp_Explorer exp( face, TopAbs_EDGE ); exp.More(); exp.Next()) { + for ( TopExp_Explorer exp( face, TopAbs_EDGE ); exp.More(); exp.Next()) + { + // look for a seam edge const TopoDS_Edge& edge = TopoDS::Edge( exp.Current() ); if ( BRep_Tool::IsClosed( edge, face )) { // initialize myPar1, myPar2 and myParIndex @@ -186,10 +189,17 @@ void SMESH_MesherHelper::SetSubShape(const TopoDS_Shape& aSh) } } // store shapes indices - mySeamShapeIds.insert( meshDS->ShapeToIndex( exp.Current() )); - for ( TopExp_Explorer v( exp.Current(), TopAbs_VERTEX ); v.More(); v.Next() ) + mySeamShapeIds.insert( meshDS->ShapeToIndex( edge )); + for ( TopExp_Explorer v( edge, TopAbs_VERTEX ); v.More(); v.Next() ) mySeamShapeIds.insert( meshDS->ShapeToIndex( v.Current() )); } + + // look for a degenerated edge + if ( BRep_Tool::Degenerated( edge )) { + myDegenShapeIds.insert( meshDS->ShapeToIndex( edge )); + for ( TopExp_Explorer v( edge, TopAbs_VERTEX ); v.More(); v.Next() ) + myDegenShapeIds.insert( meshDS->ShapeToIndex( v.Current() )); + } } } } diff --git a/src/SMESH/SMESH_MesherHelper.hxx b/src/SMESH/SMESH_MesherHelper.hxx index 7798a0e12..ad3a1e8f8 100644 --- a/src/SMESH/SMESH_MesherHelper.hxx +++ b/src/SMESH/SMESH_MesherHelper.hxx @@ -244,6 +244,15 @@ public: */ bool GetNodeUVneedInFaceNode(const TopoDS_Face& F = TopoDS_Face()) const; + /*! + * \brief Check if shape is a degenerated edge or it's vertex + * \param subShape - edge or vertex index in SMESHDS + * \retval bool - true if subShape is a degenerated shape + * + * It works only if IsQuadraticSubMesh() or SetSubShape() has been called + */ + bool IsDegenShape(const int subShape) const + { return myDegenShapeIds.find( subShape ) != myDegenShapeIds.end(); } /*! * \brief Check if shape is a seam edge or it's vertex * \param subShape - edge or vertex index in SMESHDS @@ -312,9 +321,10 @@ protected: // Forbiden copy constructor SMESH_MesherHelper (const SMESH_MesherHelper& theOther) {}; - // special map for using during creation quadratic faces + // special map for using during creation of quadratic elements NLinkNodeMap myNLinkNodeMap; + std::set< int > myDegenShapeIds; std::set< int > mySeamShapeIds; double myPar1, myPar2; // bounds of a closed periodic surface int myParIndex; // bounds' index (1-U, 2-V) diff --git a/src/SMESH/SMESH_Pattern.cxx b/src/SMESH/SMESH_Pattern.cxx index 44396d2af..5054f5549 100644 --- a/src/SMESH/SMESH_Pattern.cxx +++ b/src/SMESH/SMESH_Pattern.cxx @@ -962,7 +962,13 @@ static bool intersectIsolines(const gp_XY& uv11, const gp_XY& uv12, const double gp_XY loc1 = uv11 * ( 1 - r1 ) + uv12 * r1; gp_XY loc2 = uv21 * ( 1 - r2 ) + uv22 * r2; resUV = 0.5 * ( loc1 + loc2 ); - isDeformed = ( loc1 - loc2 ).SquareModulus() > 1e-8; + //isDeformed = ( loc1 - loc2 ).SquareModulus() > 1e-8; + // SKL 26.07.2007 for NPAL16567 + double d1 = (uv11-uv12).Modulus(); + double d2 = (uv21-uv22).Modulus(); + double delta = d1*d2*1e-6; + isDeformed = ( loc1 - loc2 ).SquareModulus() > delta; + // double len1 = ( uv11 - uv12 ).Modulus(); // double len2 = ( uv21 - uv22 ).Modulus(); // resUV = loc1 * len2 / ( len1 + len2 ) + loc2 * len1 / ( len1 + len2 ); @@ -2659,6 +2665,162 @@ bool SMESH_Pattern::Apply (const SMDS_MeshFace* theFace, return setErrorCode( ERR_OK ); } +//======================================================================= +//function : Apply +//purpose : Compute nodes coordinates applying +// the loaded pattern to . The first key-point +// will be mapped into -th node +//======================================================================= + +bool SMESH_Pattern::Apply (SMESH_Mesh* theMesh, + const SMDS_MeshFace* theFace, + const TopoDS_Shape& theSurface, + const int theNodeIndexOnKeyPoint1, + const bool theReverse) +{ +// MESSAGE(" ::Apply(MeshFace) " ); + if ( theSurface.IsNull() || theSurface.ShapeType() != TopAbs_FACE ) { + return Apply( theFace, theNodeIndexOnKeyPoint1, theReverse); + } + const TopoDS_Face& face = TopoDS::Face( theSurface ); + TopLoc_Location loc; + Handle(Geom_Surface) surface = BRep_Tool::Surface( face, loc ); + const gp_Trsf & aTrsf = loc.Transformation(); + + if ( !IsLoaded() ) { + MESSAGE( "Pattern not loaded" ); + return setErrorCode( ERR_APPL_NOT_LOADED ); + } + + // check nb of nodes + if (theFace->NbNodes() != myNbKeyPntInBoundary.front() ) { + MESSAGE( myKeyPointIDs.size() << " != " << theFace->NbNodes() ); + return setErrorCode( ERR_APPL_BAD_NB_VERTICES ); + } + + // find points on edges, it fills myNbKeyPntInBoundary + if ( !findBoundaryPoints() ) + return false; + + // check that there are no holes in a pattern + if (myNbKeyPntInBoundary.size() > 1 ) { + return setErrorCode( ERR_APPL_BAD_NB_VERTICES ); + } + + // Define the nodes order + + list< const SMDS_MeshNode* > nodes; + list< const SMDS_MeshNode* >::iterator n = nodes.end(); + SMDS_ElemIteratorPtr noIt = theFace->nodesIterator(); + int iSub = 0; + while ( noIt->more() ) { + const SMDS_MeshNode* node = smdsNode( noIt->next() ); + nodes.push_back( node ); + if ( iSub++ == theNodeIndexOnKeyPoint1 ) + n = --nodes.end(); + } + if ( n != nodes.end() ) { + if ( theReverse ) { + if ( n != --nodes.end() ) + nodes.splice( nodes.begin(), nodes, ++n, nodes.end() ); + nodes.reverse(); + } + else if ( n != nodes.begin() ) + nodes.splice( nodes.end(), nodes, nodes.begin(), n ); + } + + // find a node not on a seam edge, if necessary + SMESH_MesherHelper helper( *theMesh ); + helper.SetSubShape( theSurface ); + const SMDS_MeshNode* inFaceNode = 0; + if ( helper.GetNodeUVneedInFaceNode() ) + { + SMESH_MeshEditor editor( theMesh ); + for ( n = nodes.begin(); ( !inFaceNode && n != nodes.end()); ++n ) { + int shapeID = editor.FindShape( *n ); + if ( !shapeID ) + return Apply( theFace, theNodeIndexOnKeyPoint1, theReverse); + if ( !helper.IsSeamShape( shapeID )) + inFaceNode = *n; + } + } + + // Set UV of key-points (i.e. of nodes of theFace ) + vector< gp_XY > keyUV( theFace->NbNodes() ); + myOrderedNodes.resize( theFace->NbNodes() ); + for ( iSub = 1, n = nodes.begin(); n != nodes.end(); ++n, ++iSub ) + { + TPoint* p = getShapePoints( iSub ).front(); + p->myUV = helper.GetNodeUV( face, *n, inFaceNode ); + p->myXYZ = gp_XYZ( (*n)->X(), (*n)->Y(), (*n)->Z() ); + + keyUV[ iSub-1 ] = p->myUV; + myOrderedNodes[ iSub-1 ] = *n; + } + + // points on edges to be used for UV computation of in-face points + list< list< TPoint* > > edgesPointsList; + edgesPointsList.push_back( list< TPoint* >() ); + list< TPoint* > * edgesPoints = & edgesPointsList.back(); + list< TPoint* >::iterator pIt; + + // compute UV and XYZ of points on edges + + for ( int i = 0; i < myOrderedNodes.size(); ++i, ++iSub ) + { + gp_XY& uv1 = keyUV[ i ]; + gp_XY& uv2 = ( i+1 < keyUV.size() ) ? keyUV[ i+1 ] : keyUV[ 0 ]; + + list< TPoint* > & ePoints = getShapePoints( iSub ); + ePoints.back()->myInitU = 1.0; + list< TPoint* >::const_iterator pIt = ++ePoints.begin(); + while ( *pIt != ePoints.back() ) + { + TPoint* p = *pIt++; + p->myUV = uv1 * ( 1 - p->myInitU ) + uv2 * p->myInitU; + p->myXYZ = surface->Value( p->myUV.X(), p->myUV.Y() ); + if ( !loc.IsIdentity() ) + aTrsf.Transforms( p->myXYZ.ChangeCoord() ); + } + // collect on-edge points (excluding the last one) + edgesPoints->insert( edgesPoints->end(), ePoints.begin(), --ePoints.end()); + } + + // Compute UV and XYZ of in-face points + + // try to use a simple algo to compute UV + list< TPoint* > & fPoints = getShapePoints( iSub ); + bool isDeformed = false; + for ( pIt = fPoints.begin(); !isDeformed && pIt != fPoints.end(); pIt++ ) + if ( !compUVByIsoIntersection( edgesPointsList, (*pIt)->myInitUV, + (*pIt)->myUV, isDeformed )) { + MESSAGE("cant Apply(face)"); + return false; + } + // try to use a complex algo if it is a difficult case + if ( isDeformed && !compUVByElasticIsolines( edgesPointsList, fPoints )) + { + for ( ; pIt != fPoints.end(); pIt++ ) // continue with the simple algo + if ( !compUVByIsoIntersection( edgesPointsList, (*pIt)->myInitUV, + (*pIt)->myUV, isDeformed )) { + MESSAGE("cant Apply(face)"); + return false; + } + } + + for ( pIt = fPoints.begin(); pIt != fPoints.end(); pIt++ ) + { + TPoint * point = *pIt; + point->myXYZ = surface->Value( point->myUV.X(), point->myUV.Y() ); + if ( !loc.IsIdentity() ) + aTrsf.Transforms( point->myXYZ.ChangeCoord() ); + } + + myIsComputed = true; + + return setErrorCode( ERR_OK ); +} + //======================================================================= //function : undefinedXYZ //purpose : @@ -2687,7 +2849,8 @@ inline static bool isDefined(const gp_XYZ& theXYZ) // will be mapped into -th node //======================================================================= -bool SMESH_Pattern::Apply (std::set& theFaces, +bool SMESH_Pattern::Apply (SMESH_Mesh* theMesh, + std::set& theFaces, const int theNodeIndexOnKeyPoint1, const bool theReverse) { @@ -2725,11 +2888,29 @@ bool SMESH_Pattern::Apply (std::set& theFaces, int ind1 = 0; // lowest point index for a face + // meshed geometry + TopoDS_Shape shape; +// int shapeID = 0; +// SMESH_MeshEditor editor( theMesh ); + // apply to each face in theFaces set set::iterator face = theFaces.begin(); for ( ; face != theFaces.end(); ++face ) { - if ( !Apply( *face, theNodeIndexOnKeyPoint1, theReverse )) { +// int curShapeId = editor.FindShape( *face ); +// if ( curShapeId != shapeID ) { +// if ( curShapeId ) +// shape = theMesh->GetMeshDS()->IndexToShape( curShapeId ); +// else +// shape.Nullify(); +// shapeID = curShapeId; +// } + bool ok; + if ( shape.IsNull() ) + ok = Apply( *face, theNodeIndexOnKeyPoint1, theReverse ); + else + ok = Apply( theMesh, *face, shape, theNodeIndexOnKeyPoint1, theReverse ); + if ( !ok ) { MESSAGE( "Failed on " << *face ); continue; } @@ -3905,7 +4086,7 @@ void SMESH_Pattern::createElements(SMESH_Mesh* theMes SMESH_subMesh * subMesh; if ( !myShape.IsNull() ) { - subMesh = theMesh->GetSubMeshContaining( myShape ); + subMesh = theMesh->GetSubMesh( myShape ); if ( subMesh ) subMesh->ComputeStateEngine( SMESH_subMesh::CHECK_COMPUTE_STATE ); } diff --git a/src/SMESH/SMESH_Pattern.hxx b/src/SMESH/SMESH_Pattern.hxx index 9699064ad..df1ccd0eb 100644 --- a/src/SMESH/SMESH_Pattern.hxx +++ b/src/SMESH/SMESH_Pattern.hxx @@ -103,7 +103,17 @@ class SMESH_EXPORT SMESH_Pattern { // the loaded pattern to . The first key-point // will be mapped into -th node - bool Apply (std::set& theFaces, + bool Apply (SMESH_Mesh* theMesh, + const SMDS_MeshFace* theFace, + const TopoDS_Shape& theSurface, + const int theNodeIndexOnKeyPoint1, + const bool theReverse); + // Compute nodes coordinates applying + // the loaded pattern to . The first key-point + // will be mapped into -th node + + bool Apply (SMESH_Mesh* theMesh, + std::set& theFaces, const int theNodeIndexOnKeyPoint1, const bool theReverse); // Compute nodes coordinates applying diff --git a/src/SMESH/SMESH_subMesh.cxx b/src/SMESH/SMESH_subMesh.cxx index 6b358d329..e766df8ef 100644 --- a/src/SMESH/SMESH_subMesh.cxx +++ b/src/SMESH/SMESH_subMesh.cxx @@ -53,11 +53,26 @@ #include #include -#include +#include #include using namespace std; +//============================================================================= +/*! + * \brief Allocate some memory at construction and release it at destruction. + * Is used to be able to continue working after mesh generation breaks due to + * lack of memory + */ +//============================================================================= + +struct MemoryReserve +{ + char* myBuf; + MemoryReserve(): myBuf( new char[1024*1024*2] ){} + ~MemoryReserve() { delete [] myBuf; } +}; + //============================================================================= /*! * default constructor: @@ -608,49 +623,6 @@ SMESH_Hypothesis::Hypothesis_Status if ( !meshDS->AddHypothesis(_subShape, anHyp)) return SMESH_Hypothesis::HYP_ALREADY_EXIST; - - // Serve Propagation of 1D hypothesis - // NOTE: it is possible to re-implement Propagation using EventListener - if (event == ADD_HYP) { - bool isPropagationOk = true; - bool isPropagationHyp = ( strcmp( "Propagation", anHyp->GetName() ) == 0 ); - - if ( isPropagationHyp ) { - TopExp_Explorer exp (_subShape, TopAbs_EDGE); - TopTools_MapOfShape aMap; - for (; exp.More(); exp.Next()) { - if (aMap.Add(exp.Current())) { - if (!_father->BuildPropagationChain(exp.Current())) { - isPropagationOk = false; - } - } - } - } - else if (anHyp->GetDim() == 1) { // Only 1D hypothesis can be propagated - TopExp_Explorer exp (_subShape, TopAbs_EDGE); - TopTools_MapOfShape aMap; - for (; exp.More(); exp.Next()) { - if (aMap.Add(exp.Current())) { - TopoDS_Shape aMainEdge; - if (_father->IsPropagatedHypothesis(exp.Current(), aMainEdge)) { - isPropagationOk = _father->RebuildPropagationChains(); - } else if (_father->IsPropagationHypothesis(exp.Current())) { - isPropagationOk = _father->BuildPropagationChain(exp.Current()); - } else { - } - } - } - } else { - } - - if ( isPropagationOk ) { - if ( isPropagationHyp ) - return ret; // nothing more to do for "Propagation" hypothesis - } - else if ( ret < SMESH_Hypothesis::HYP_CONCURENT) { - ret = SMESH_Hypothesis::HYP_CONCURENT; - } - } // Serve Propagation of 1D hypothesis } // -------------------------- @@ -661,45 +633,7 @@ SMESH_Hypothesis::Hypothesis_Status if (!meshDS->RemoveHypothesis(_subShape, anHyp)) return SMESH_Hypothesis::HYP_OK; // nothing changes - // Serve Propagation of 1D hypothesis - // NOTE: it is possible to re-implement Propagation using EventListener - if (event == REMOVE_HYP) - { - bool isPropagationOk = true; - SMESH_HypoFilter propagFilter( SMESH_HypoFilter::HasName( "Propagation" )); - bool isPropagationHyp = propagFilter.IsOk( anHyp, _subShape ); - - if ( isPropagationHyp ) - { - TopExp_Explorer exp (_subShape, TopAbs_EDGE); - TopTools_MapOfShape aMap; - for (; exp.More(); exp.Next()) { - if (aMap.Add(exp.Current()) && - !_father->GetHypothesis( exp.Current(), propagFilter, true )) { - // no more Propagation on the current edge - if (!_father->RemovePropagationChain(exp.Current())) { - return SMESH_Hypothesis::HYP_UNKNOWN_FATAL; - } - } - } - // rebuild propagation chains, because removing one - // chain can resolve concurention, existing before - isPropagationOk = _father->RebuildPropagationChains(); - } - else if (anHyp->GetDim() == 1) // Only 1D hypothesis can be propagated - { - isPropagationOk = _father->RebuildPropagationChains(); - } - - if ( isPropagationOk ) { - if ( isPropagationHyp ) - return ret; // nothing more to do for "Propagation" hypothesis - } - else if ( ret < SMESH_Hypothesis::HYP_CONCURENT) { - ret = SMESH_Hypothesis::HYP_CONCURENT; - } - } // Serve Propagation of 1D hypothesis - else // event == REMOVE_ALGO + if (event == REMOVE_ALGO) { algo = dynamic_cast (anHyp); if (!algo->NeedDescretBoundary()) @@ -1365,7 +1299,8 @@ bool SMESH_subMesh::ComputeStateEngine(int event) _computeState = FAILED_TO_COMPUTE; if ( !algo->NeedDescretBoundary() ) _computeError = - SMESH_ComputeError::New(COMPERR_BAD_INPUT_MESH,"Unexpected submesh",algo); + SMESH_ComputeError::New(COMPERR_BAD_INPUT_MESH, + "Unexpected computed submesh",algo); break; } } @@ -1380,11 +1315,12 @@ bool SMESH_subMesh::ComputeStateEngine(int event) #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100 OCC_CATCH_SIGNALS; #endif + MemoryReserve aMemoryReserve; algo->InitComputeError(); if ( !_father->HasShapeToMesh() ) // no shape { SMESH_MesherHelper helper( *_father ); - helper.SetSubShape( _subShape ); + helper.SetSubShape( shape ); helper.SetElementsOnShape( true ); ret = algo->Compute(*_father, &helper ); } @@ -1393,34 +1329,43 @@ bool SMESH_subMesh::ComputeStateEngine(int event) if (!algo->OnlyUnaryInput()) { shape = GetCollection( gen, algo ); } - if (!algo->NeedDescretBoundary() && !algo->OnlyUnaryInput()) { - ret = ApplyToCollection( algo, shape ); - break; - } - else { - ret = algo->Compute((*_father), shape); - } + ret = algo->Compute((*_father), shape); } if ( !ret ) _computeError = algo->GetComputeError(); } - catch (Standard_Failure& exc) { + catch ( std::bad_alloc& exc ) { + printf("std::bad_alloc\n"); + if ( _computeError ) { + _computeError->myName = COMPERR_MEMORY_PB; + //_computeError->myComment = exc.what(); + } + cleanSubMesh( this ); + throw exc; + } + catch ( Standard_OutOfMemory& exc ) { + printf("Standard_OutOfMemory\n"); + if ( _computeError ) { + _computeError->myName = COMPERR_MEMORY_PB; + //_computeError->myComment = exc.what(); + } + cleanSubMesh( this ); + throw std::bad_alloc(); + } + catch (Standard_Failure& ex) { if ( !_computeError ) _computeError = SMESH_ComputeError::New(); _computeError->myName = COMPERR_OCC_EXCEPTION; - _computeError->myComment = exc.GetMessageString(); + _computeError->myComment += ex.DynamicType()->Name(); + if ( ex.GetMessageString() && strlen( ex.GetMessageString() )) { + _computeError->myComment += ": "; + _computeError->myComment += ex.GetMessageString(); + } } catch ( SALOME_Exception& S_ex ) { if ( !_computeError ) _computeError = SMESH_ComputeError::New(); _computeError->myName = COMPERR_SLM_EXCEPTION; _computeError->myComment = S_ex.what(); } - catch ( std::bad_alloc& exc ) { - if ( _computeError ) { - _computeError->myName = COMPERR_MEMORY_PB; - _computeError->myComment = exc.what(); - } - throw exc; - } catch ( std::exception& exc ) { if ( !_computeError ) _computeError = SMESH_ComputeError::New(); _computeError->myName = COMPERR_STD_EXCEPTION; @@ -1432,28 +1377,25 @@ bool SMESH_subMesh::ComputeStateEngine(int event) else ret = false; } - if ( ret && _computeError && !_computeError->IsOK() ) { - ret = false; - } if (ret && !_alwaysComputed) { // check if anything was built ret = ( GetSubMeshDS() && ( GetSubMeshDS()->NbElements() || GetSubMeshDS()->NbNodes() )); } - if (!ret) + bool isComputeErrorSet = !CheckComputeError( algo, shape ); + if (!ret && !isComputeErrorSet) { // Set _computeError if ( !_computeError ) _computeError = SMESH_ComputeError::New(); if ( _computeError->IsOK() ) _computeError->myName = COMPERR_ALGO_FAILED; + _computeState = FAILED_TO_COMPUTE; } - else + if (ret) { _computeError.reset(); //UpdateDependantsState( SUBMESH_COMPUTED ); // send event SUBMESH_COMPUTED } - //if ( !algo->NeedDescretBoundary() ) - // UpdateSubMeshState( ret ? COMPUTE_OK : FAILED_TO_COMPUTE ); - CheckComputeError( algo, shape ); + UpdateDependantsState( SUBMESH_COMPUTED ); // send event SUBMESH_COMPUTED } break; case CLEAN: @@ -1596,54 +1538,78 @@ bool SMESH_subMesh::ComputeStateEngine(int event) /*! * \brief Update compute_state by _computeError and send proper events to * dependent submeshes + * \retval bool - true if _computeError is NOT set */ //======================================================================= bool SMESH_subMesh::CheckComputeError(SMESH_Algo* theAlgo, const TopoDS_Shape& theShape) { - bool noErrors = ( !_computeError || _computeError->IsOK() ); - if ( !noErrors ) + bool noErrors = true; + + if ( !theShape.IsNull() ) + { + // Check state of submeshes + if ( !theAlgo->NeedDescretBoundary()) + { + SMESH_subMeshIteratorPtr smIt = getDependsOnIterator(false,false); + while ( smIt->more() ) + if ( !smIt->next()->CheckComputeError( theAlgo )) + noErrors = false; + } + + // Check state of neighbours + if ( !theAlgo->OnlyUnaryInput() && + theShape.ShapeType() == TopAbs_COMPOUND && + !theShape.IsSame( _subShape )) + { + for (TopoDS_Iterator subIt( theShape ); subIt.More(); subIt.Next()) { + SMESH_subMesh* sm = _father->GetSubMesh( subIt.Value() ); + if ( sm != this ) { + if ( !sm->CheckComputeError( theAlgo )) + noErrors = false; + UpdateDependantsState( SUBMESH_COMPUTED ); // send event SUBMESH_COMPUTED + } + } + } + } { - if ( !_computeError->myAlgo ) - _computeError->myAlgo = theAlgo; - - // Show error - SMESH_Comment text; - text << theAlgo->GetName() << " failed on subshape " << _Id << " with error "; - if (_computeError->IsCommon() ) - text << _computeError->CommonName(); + // Check my state + if ( !_computeError || _computeError->IsOK() ) + { + _computeState = COMPUTE_OK; + } else - text << _computeError->myName; - if ( _computeError->myComment.size() > 0 ) - text << " \"" << _computeError->myComment << "\""; + { + if ( !_computeError->myAlgo ) + _computeError->myAlgo = theAlgo; + + // Show error + SMESH_Comment text; + text << theAlgo->GetName() << " failed on subshape #" << _Id << " with error "; + if (_computeError->IsCommon() ) + text << _computeError->CommonName(); + else + text << _computeError->myName; + if ( _computeError->myComment.size() > 0 ) + text << " \"" << _computeError->myComment << "\""; #ifdef _DEBUG_ - cout << text << endl; - // Show vertices location of a failed shape - cout << "Subshape vertices (first 10):" << endl; - TopTools_IndexedMapOfShape vMap; - TopExp::MapShapes( _subShape, TopAbs_VERTEX, vMap ); - for ( int iv = 1; iv <= vMap.Extent() && iv < 11; ++iv ) { - gp_Pnt P( BRep_Tool::Pnt( TopoDS::Vertex( vMap( iv ) ))); - cout << P.X() << " " << P.Y() << " " << P.Z() << " " << endl; - } + cout << text << endl; + // Show vertices location of a failed shape + TopTools_IndexedMapOfShape vMap; + TopExp::MapShapes( _subShape, TopAbs_VERTEX, vMap ); + cout << "Subshape vertices " << ( vMap.Extent()>10 ? "(first 10):" : ":") << endl; + for ( int iv = 1; iv <= vMap.Extent() && iv < 11; ++iv ) { + gp_Pnt P( BRep_Tool::Pnt( TopoDS::Vertex( vMap( iv ) ))); + cout << "#" << _father->GetMeshDS()->ShapeToIndex( vMap( iv )) << " "; + cout << P.X() << " " << P.Y() << " " << P.Z() << " " << endl; + } #else - INFOS( text ); + INFOS( text ); #endif - _computeState = FAILED_TO_COMPUTE; - } - else - { - _computeState = COMPUTE_OK; - UpdateDependantsState( SUBMESH_COMPUTED ); // send event SUBMESH_COMPUTED - } - // Check state of submeshes - if ( !theAlgo->NeedDescretBoundary() ) - { - SMESH_subMeshIteratorPtr smIt = getDependsOnIterator(false,false); - while ( smIt->more() ) - if ( !smIt->next()->CheckComputeError( theAlgo )) - noErrors = false; + _computeState = FAILED_TO_COMPUTE; + noErrors = false; + } } if ( !theAlgo->OnlyUnaryInput() && !theShape.IsNull() && theShape.ShapeType() == TopAbs_COMPOUND ) diff --git a/src/SMESHDS/SMESHDS_SubMesh.hxx b/src/SMESHDS/SMESHDS_SubMesh.hxx index 1231c490c..fa885cefd 100644 --- a/src/SMESHDS/SMESHDS_SubMesh.hxx +++ b/src/SMESHDS/SMESHDS_SubMesh.hxx @@ -48,6 +48,7 @@ class SMESHDS_EXPORT SMESHDS_SubMesh void AddSubMesh( const SMESHDS_SubMesh* theSubMesh ); bool RemoveSubMesh( const SMESHDS_SubMesh* theSubMesh ); bool ContainsSubMesh( const SMESHDS_SubMesh* theSubMesh ) const; + int NbSubMeshes() const { return mySubMeshes.size(); } // for both types int NbElements() const; diff --git a/src/SMESHDS/SMESH_SMESHDS.hxx b/src/SMESHDS/SMESH_SMESHDS.hxx index fdef18da9..6747798ef 100755 --- a/src/SMESHDS/SMESH_SMESHDS.hxx +++ b/src/SMESHDS/SMESH_SMESHDS.hxx @@ -36,4 +36,4 @@ #define SMESHDS_EXPORT #endif -#endif \ No newline at end of file +#endif diff --git a/src/SMESHGUI/SMESHGUI.cxx b/src/SMESHGUI/SMESHGUI.cxx index 89ce6fe7a..9cedb02fa 100644 --- a/src/SMESHGUI/SMESHGUI.cxx +++ b/src/SMESHGUI/SMESHGUI.cxx @@ -308,7 +308,7 @@ using namespace std; there must be check on others mesh elements not equal triangles */ if (aMesh->NbTriangles() < 1) { - int aRet = SUIT_MessageBox::warn1 + SUIT_MessageBox::warn1 (SMESHGUI::desktop(), QObject::tr("SMESH_WRN_WARNING"), QObject::tr("SMESH_EXPORT_STL1").arg(anIObject->getName()), @@ -1857,17 +1857,18 @@ bool SMESHGUI::OnGUIEvent( int theCommandID ) int nbSel = selected.Extent(); if (nbSel == 1) { - SMESH::SMESH_Hypothesis_var Hyp = SMESH::IObjectToInterface(selected.First()); + Handle(SALOME_InteractiveObject) anIObject = selected.First(); + SMESH::SMESH_Hypothesis_var aHypothesis = SMESH::IObjectToInterface(anIObject); /* Look for all mesh objects that have this hypothesis affected in order to flag as ModifiedMesh */ /* At end below '...->updateObjBrowser(true)' will change icon of mesh objects */ /* Warning : however by internal mechanism all subMeshes icons are changed ! */ - if ( !Hyp->_is_nil() ) + if ( !aHypothesis->_is_nil() ) { - char* sName = Hyp->GetName(); - SMESHGUI_GenericHypothesisCreator* aCreator = SMESH::GetHypothesisCreator(sName); + CORBA::String_var aHypType = aHypothesis->GetName(); + SMESHGUI_GenericHypothesisCreator* aCreator = SMESH::GetHypothesisCreator(aHypType); if (aCreator) - aCreator->edit( Hyp.in(), desktop() ); + aCreator->edit( aHypothesis.in(), anIObject->getName(), desktop() ); else { // report error @@ -3097,7 +3098,7 @@ void SMESHGUI::createPreferences() int exportgroup = addPreference( tr( "PREF_GROUP_EXPORT" ), genTab ); addPreference( tr( "PREF_AUTO_GROUPS" ), exportgroup, LightApp_Preferences::Bool, "SMESH", "auto_groups" ); - int renumber=addPreference( tr( "PREF_RENUMBER" ), exportgroup, LightApp_Preferences::Bool, "SMESH", "renumbering" ); + addPreference( tr( "PREF_RENUMBER" ), exportgroup, LightApp_Preferences::Bool, "SMESH", "renumbering" ); int meshTab = addPreference( tr( "PREF_TAB_MESH" ) ); int nodeGroup = addPreference( tr( "PREF_GROUP_NODES" ), meshTab ); diff --git a/src/SMESHGUI/SMESHGUI_ComputeDlg.cxx b/src/SMESHGUI/SMESHGUI_ComputeDlg.cxx index 5ce986876..6c856bb78 100644 --- a/src/SMESHGUI/SMESHGUI_ComputeDlg.cxx +++ b/src/SMESHGUI/SMESHGUI_ComputeDlg.cxx @@ -77,6 +77,7 @@ #include #include #include +#include #include @@ -109,6 +110,21 @@ using namespace SMESH; namespace SMESH { + //============================================================================= + /*! + * \brief Allocate some memory at construction and release it at destruction. + * Is used to be able to continue working after mesh generation or visualization + * break due to lack of memory + */ + //============================================================================= + + struct MemoryReserve + { + char* myBuf; + MemoryReserve(): myBuf( new char[1024*1024*1] ){} // 1M + ~MemoryReserve() { delete [] myBuf; } + }; + // ========================================================================================= /*! * \brief Class showing shapes without publishing @@ -573,7 +589,7 @@ void SMESHGUI_MeshInfosBox::SetInfoByMesh(SMESH::SMESH_Mesh_var mesh) // faces nbTot = mesh->NbFaces(), nbLin = mesh->NbFacesOfOrder(lin); myNbFace ->setText( QString("%1").arg( nbTot )); - myNbLinFace ->setText( QString("%1").arg( nbLin )); + myNbLinFace ->setText( QString("%1").arg( nbLin )); myNbQuadFace ->setText( QString("%1").arg( nbTot - nbLin )); // volumes @@ -706,12 +722,22 @@ QFrame* SMESHGUI_ComputeDlg::createMainFrame (QWidget* theParent) grpLayout->addWidget ( myPublishBtn, 1, 1 ); grpLayout->setRowStretch( 2, 1 ); + // Memory Lack Label + + myMemoryLackGroup = new QVGroupBox(tr("ERRORS"), aFrame, "memlackGrBox"); + QLabel* memLackLabel = new QLabel(tr("MEMORY_LACK"), myMemoryLackGroup); + QFont bold = memLackLabel->font(); bold.setBold(true); + memLackLabel->setFont( bold ); + memLackLabel->setMinimumWidth(300); + + // add all widgets to aFrame QVBoxLayout* aLay = new QVBoxLayout(aFrame); aLay->addWidget( aPixGrp ); aLay->addWidget( nameBox ); aLay->addWidget( myBriefInfo ); aLay->addWidget( myFullInfo ); aLay->addWidget( myErrorGroup ); + aLay->addWidget( myMemoryLackGroup ); aLay->setStretchFactor( myErrorGroup, 1 ); return aFrame; @@ -751,7 +777,7 @@ void SMESHGUI_ComputeOp::startOperation() // COMPUTE MESH - bool computeFailed = true; + bool computeFailed = true, memoryLack = false; int nbNodes = 0, nbEdges = 0, nbFaces = 0, nbVolums = 0; LightApp_SelectionMgr *Sel = selectionMgr(); @@ -769,9 +795,14 @@ void SMESHGUI_ComputeOp::startOperation() Handle(SALOME_InteractiveObject) IObject = selected.First(); aMesh = SMESH::GetMeshByIO(IObject); - if (!aMesh->_is_nil()) { + if (!aMesh->_is_nil()) + { + MemoryReserve aMemoryReserve; + _PTR(SObject) aMeshSObj = SMESH::FindSObject(aMesh); myMainShape = aMesh->GetShapeToMesh(); - if ( !myMainShape->_is_nil() ) { + if ( !myMainShape->_is_nil() && aMeshSObj ) + { + myDlg->myMeshName->setText( aMeshSObj->GetName() ); SMESH::SMESH_Gen_var gen = getSMESHGUI()->GetSMESHGen(); SMESH::algo_error_array_var errors = gen->GetAlgoState(aMesh,myMainShape); if ( errors->length() > 0 ) { @@ -783,49 +814,62 @@ void SMESHGUI_ComputeOp::startOperation() } SUIT_OverrideCursor aWaitCursor; try { - if (gen->Compute(aMesh, myMainShape)) { + if (gen->Compute(aMesh, myMainShape)) computeFailed = false; - } - else { - anErrors = gen->GetComputeErrors( aMesh, myMainShape ); -// if ( anErrors->length() == 0 ) { -// SUIT_MessageBox::warn1(desktop(), -// tr("SMESH_WRN_WARNING"), -// tr("SMESH_WRN_COMPUTE_FAILED"), -// tr("SMESH_BUT_OK")); -// onCancel(); -// return; -// } - } } catch(const SALOME::SALOME_Exception & S_ex){ - SalomeApp_Tools::QtCatchCorbaException(S_ex); + memoryLack = true; + //SalomeApp_Tools::QtCatchCorbaException(S_ex); } - if ( _PTR(SObject) aMeshSObj = SMESH::FindSObject(aMesh)) { - myDlg->myMeshName->setText( aMeshSObj->GetName() ); - SMESH::ModifiedMesh(aMeshSObj, !computeFailed, aMesh->NbNodes() == 0); + try { + anErrors = gen->GetComputeErrors( aMesh, myMainShape ); + // if ( anErrors->length() == 0 ) { + // SUIT_MessageBox::warn1(desktop(), + // tr("SMESH_WRN_WARNING"), + // tr("SMESH_WRN_COMPUTE_FAILED"), + // tr("SMESH_BUT_OK")); + // onCancel(); + // return; + // } + // check if there are memory problems + for ( int i = 0; i < anErrors->length() && !memoryLack; ++i ) + memoryLack = ( anErrors[ i ].code == SMESH::COMPERR_MEMORY_PB ); } - update( UF_ObjBrowser | UF_Model ); - - // SHOW MESH - - if ( getSMESHGUI()->automaticUpdate() ) { - SVTK_ViewWindow* aVTKView = SMESH::GetViewWindow(getSMESHGUI(), true); - if (aVTKView) { - int anId = study()->id(); - TVisualObjPtr aVisualObj = SMESH::GetVisualObj(anId, IObject->getEntry()); - if (aVisualObj) { - aVisualObj->Update(); - SMESH_Actor* anActor = SMESH::FindActorByEntry(IObject->getEntry()); - if (!anActor) { - anActor = SMESH::CreateActor(studyDS(), IObject->getEntry()); - if (anActor) { - SMESH::DisplayActor(aVTKView, anActor); //apo - SMESH::FitAll(); + catch(const SALOME::SALOME_Exception & S_ex){ + memoryLack = true; + } + + // NPAL16631: if ( !memoryLack ) + { + SMESH::ModifiedMesh(aMeshSObj, !computeFailed, aMesh->NbNodes() == 0); + update( UF_ObjBrowser | UF_Model ); + + // SHOW MESH + // NPAL16631: if ( getSMESHGUI()->automaticUpdate() ) { + if ( !memoryLack && getSMESHGUI()->automaticUpdate() ) // NPAL16631 + { + try { + SVTK_ViewWindow* aVTKView = SMESH::GetViewWindow(getSMESHGUI(), true); + if (aVTKView) { + int anId = study()->id(); + TVisualObjPtr aVisualObj = SMESH::GetVisualObj(anId, IObject->getEntry()); + if (aVisualObj) { + aVisualObj->Update(); + SMESH_Actor* anActor = SMESH::FindActorByEntry(IObject->getEntry()); + if (!anActor) { + anActor = SMESH::CreateActor(studyDS(), IObject->getEntry()); + if (anActor) { + SMESH::DisplayActor(aVTKView, anActor); //apo + SMESH::FitAll(); + } + } + SMESH::RepaintCurrentView(); + Sel->setSelectedObjects( selected ); } } - SMESH::RepaintCurrentView(); - Sel->setSelectedObjects( selected ); + } + catch (...) { + memoryLack = true; } } } @@ -839,18 +883,22 @@ void SMESHGUI_ComputeOp::startOperation() onCancel(); return; } - myDlg->setCaption(tr( computeFailed ? "SMESH_WRN_COMPUTE_FAILED" : "SMESH_COMPUTE_SUCCEED")); + myDlg->myMemoryLackGroup->hide(); // SHOW ERRORS bool noError = ( !anErrors.operator->() || anErrors->length() == 0 ); - QTable* tbl = myDlg->myTable; - - if ( noError ) + if ( memoryLack ) + { + myDlg->myMemoryLackGroup->show(); + myDlg->myFullInfo->hide(); + myDlg->myBriefInfo->hide(); + myDlg->myErrorGroup->hide(); + } + else if ( noError ) { - //tbl->setNumRows(0); myDlg->myFullInfo->SetInfoByMesh( aMesh ); myDlg->myFullInfo->show(); myDlg->myBriefInfo->hide(); @@ -858,6 +906,7 @@ void SMESHGUI_ComputeOp::startOperation() } else { + QTable* tbl = myDlg->myTable; myDlg->myBriefInfo->SetInfoByMesh( aMesh ); myDlg->myBriefInfo->show(); myDlg->myFullInfo->hide(); @@ -892,7 +941,6 @@ void SMESHGUI_ComputeOp::startOperation() tbl->setCurrentCell(0,0); currentCellChanged(); // to update buttons } - myDlg->show(); } diff --git a/src/SMESHGUI/SMESHGUI_ComputeDlg.h b/src/SMESHGUI/SMESHGUI_ComputeDlg.h index bb4252475..5e22e2b5a 100644 --- a/src/SMESHGUI/SMESHGUI_ComputeDlg.h +++ b/src/SMESHGUI/SMESHGUI_ComputeDlg.h @@ -130,6 +130,7 @@ private: QFrame* createMainFrame (QWidget*); QLabel* myMeshName; + QGroupBox* myMemoryLackGroup; QGroupBox* myErrorGroup; QTable* myTable; QPushButton* myShowBtn; diff --git a/src/SMESHGUI/SMESHGUI_FilterDlg.cxx b/src/SMESHGUI/SMESHGUI_FilterDlg.cxx index 2b75ac0c4..59a3eda1a 100755 --- a/src/SMESHGUI/SMESHGUI_FilterDlg.cxx +++ b/src/SMESHGUI/SMESHGUI_FilterDlg.cxx @@ -2540,7 +2540,8 @@ void SMESHGUI_FilterDlg::onSelectionDone() if (!anObj->_is_nil()) { myTable->SetThreshold(aRow, GEOMBase::GetName(anObj)); - myTable->SetID( aRow, GEOMBase::GetIORFromObject(anObj)); + //myTable->SetID( aRow, GEOMBase::GetIORFromObject(anObj)); + myTable->SetID(aRow, anIO->getEntry()); } } diff --git a/src/SMESHGUI/SMESHGUI_Hypotheses.cxx b/src/SMESHGUI/SMESHGUI_Hypotheses.cxx index e94a8a993..7414bf5ff 100644 --- a/src/SMESHGUI/SMESHGUI_Hypotheses.cxx +++ b/src/SMESHGUI/SMESHGUI_Hypotheses.cxx @@ -45,8 +45,8 @@ #include -SMESHGUI_GenericHypothesisCreator::SMESHGUI_GenericHypothesisCreator( const QString& aHypType ) - : myHypType( aHypType ), myIsCreate( false ), myDlg( 0 ) +SMESHGUI_GenericHypothesisCreator::SMESHGUI_GenericHypothesisCreator( const QString& theHypType ) + : myHypType( theHypType ), myIsCreate( false ), myDlg( 0 ) { } @@ -55,63 +55,62 @@ SMESHGUI_GenericHypothesisCreator::~SMESHGUI_GenericHypothesisCreator() } void SMESHGUI_GenericHypothesisCreator::create( SMESH::SMESH_Hypothesis_ptr initParamsHyp, + const QString& theHypName, QWidget* parent) { MESSAGE( "Creation of hypothesis with initial params" ); if ( !CORBA::is_nil( initParamsHyp ) && hypType() == initParamsHyp->GetName() ) myInitParamsHypo = SMESH::SMESH_Hypothesis::_duplicate( initParamsHyp ); - create( false, parent ); + create( false, theHypName, parent ); } -void SMESHGUI_GenericHypothesisCreator::create( const bool isAlgo, QWidget* parent ) +void SMESHGUI_GenericHypothesisCreator::create( bool isAlgo, + const QString& theHypName, + QWidget* theParent ) { MESSAGE( "Creation of hypothesis" ); - // Get default name for hypothesis/algorithm creation - HypothesisData* aHypData = SMESH::GetHypothesisData( hypType().latin1() ); - QString aHypName = aHypData ? aHypData->Label : hypType(); - myIsCreate = true; // Create hypothesis/algorithm if (isAlgo) - SMESH::CreateHypothesis( hypType(), aHypName, isAlgo ); - + SMESH::CreateHypothesis( hypType(), theHypName, isAlgo ); else { - SMESH::SMESH_Hypothesis_var newHypo = SMESH::SMESH_Hypothesis::_narrow - ( SMESH::CreateHypothesis( hypType(), aHypName, false ) ); - - if( !editHypothesis( newHypo.in(), parent ) ) + SMESH::SMESH_Hypothesis_var aHypothesis = + SMESH::CreateHypothesis( hypType(), theHypName, false ); + if( !editHypothesis( aHypothesis.in(), theHypName, theParent ) ) { //remove just created hypothesis - _PTR(SObject) SHyp = SMESH::FindSObject( newHypo.in() ); + _PTR(SObject) aHypSObject = SMESH::FindSObject( aHypothesis.in() ); _PTR(Study) aStudy = SMESH::GetActiveStudyDocument(); if( aStudy && !aStudy->GetProperties()->IsLocked() ) { _PTR(StudyBuilder) aBuilder = aStudy->NewBuilder(); - aBuilder->RemoveObjectWithChildren( SHyp ); + aBuilder->RemoveObjectWithChildren( aHypSObject ); } } } SMESHGUI::GetSMESHGUI()->updateObjBrowser( true, 0 ); } -void SMESHGUI_GenericHypothesisCreator::edit( SMESH::SMESH_Hypothesis_ptr h, QWidget* parent ) +void SMESHGUI_GenericHypothesisCreator::edit( SMESH::SMESH_Hypothesis_ptr theHypothesis, + const QString& theHypName, + QWidget* theParent ) { - if( CORBA::is_nil( h ) ) + if( CORBA::is_nil( theHypothesis ) ) return; MESSAGE("Edition of hypothesis"); myIsCreate = false; - if( !editHypothesis( h, parent ) ) + if( !editHypothesis( theHypothesis, theHypName, theParent ) ) return; - SMESH::SObjectList listSOmesh = SMESH::GetMeshesUsingAlgoOrHypothesis( h ); + SMESH::SObjectList listSOmesh = SMESH::GetMeshesUsingAlgoOrHypothesis( theHypothesis ); if( listSOmesh.size() > 0 ) - for( int i=0; i( submSO ); @@ -124,29 +123,30 @@ void SMESHGUI_GenericHypothesisCreator::edit( SMESH::SMESH_Hypothesis_ptr h, QWi SMESHGUI::GetSMESHGUI()->updateObjBrowser( true, 0 ); } -bool SMESHGUI_GenericHypothesisCreator::editHypothesis( SMESH::SMESH_Hypothesis_ptr h, QWidget* parent ) +bool SMESHGUI_GenericHypothesisCreator::editHypothesis( SMESH::SMESH_Hypothesis_ptr h, + const QString& theHypName, + QWidget* theParent ) { if( CORBA::is_nil( h ) ) return false; bool res = true; + myHypName = theHypName; myHypo = SMESH::SMESH_Hypothesis::_duplicate( h ); - SMESHGUI_HypothesisDlg* Dlg = - new SMESHGUI_HypothesisDlg( const_cast( this ), parent ); + SMESHGUI_HypothesisDlg* Dlg = new SMESHGUI_HypothesisDlg( this, theParent ); myDlg = Dlg; QFrame* fr = buildFrame(); if( fr ) { Dlg->setCustomFrame( fr ); Dlg->setCaption( caption() ); + Dlg->setName( theHypName ); Dlg->setHIcon( icon() ); Dlg->setType( type() ); retrieveParams(); Dlg->show(); - //connect(myDlg, SIGNAL( closed() ), this, SLOT( onDlgClosed() )); qApp->enter_loop(); // make myDlg not modal -// res = myDlg->exec()==QDialog::Accepted; res = myDlg->result(); if( res ) { QString paramValues = storeParams(); @@ -332,6 +332,11 @@ QString SMESHGUI_GenericHypothesisCreator::hypType() const return myHypType; } +QString SMESHGUI_GenericHypothesisCreator::hypName() const +{ + return myHypName; +} + const SMESHGUI_GenericHypothesisCreator::ListOfWidgets& SMESHGUI_GenericHypothesisCreator::widgets() const { return myParamWidgets; diff --git a/src/SMESHGUI/SMESHGUI_Hypotheses.h b/src/SMESHGUI/SMESHGUI_Hypotheses.h index c76e409e1..b411cf7b8 100644 --- a/src/SMESHGUI/SMESHGUI_Hypotheses.h +++ b/src/SMESHGUI/SMESHGUI_Hypotheses.h @@ -47,18 +47,19 @@ class SMESHGUI_EXPORT SMESHGUI_GenericHypothesisCreator : public QObject Q_OBJECT public: - SMESHGUI_GenericHypothesisCreator( const QString& ); + SMESHGUI_GenericHypothesisCreator( const QString& theHypType ); virtual ~SMESHGUI_GenericHypothesisCreator(); - void create( const bool isAlgo, QWidget* ); - void edit( SMESH::SMESH_Hypothesis_ptr, QWidget* ); - void create( SMESH::SMESH_Hypothesis_ptr, QWidget* ); + void create( SMESH::SMESH_Hypothesis_ptr, const QString&, QWidget*); + void create( bool isAlgo, const QString&, QWidget*); + void edit( SMESH::SMESH_Hypothesis_ptr, const QString&, QWidget*); virtual bool checkParams() const = 0; virtual void onReject(); - QString hypType() const; - bool isCreation() const; + QString hypType() const; + QString hypName() const; + bool isCreation() const; protected: typedef struct @@ -95,10 +96,11 @@ protected slots: virtual void onValueChanged(); private: - bool editHypothesis( SMESH::SMESH_Hypothesis_ptr, QWidget* ); + bool editHypothesis( SMESH::SMESH_Hypothesis_ptr, const QString&, QWidget* ); private: SMESH::SMESH_Hypothesis_var myHypo, myInitParamsHypo; + QString myHypName; QString myHypType; ListOfWidgets myParamWidgets; bool myIsCreate; @@ -113,9 +115,9 @@ public: SMESHGUI_HypothesisDlg( SMESHGUI_GenericHypothesisCreator*, QWidget* ); virtual ~SMESHGUI_HypothesisDlg(); - void setHIcon( const QPixmap& ); - void setCustomFrame( QFrame* ); - void setType( const QString& ); + void setHIcon( const QPixmap& ); + void setCustomFrame( QFrame* ); + void setType( const QString& ); protected slots: virtual void accept(); @@ -125,7 +127,8 @@ protected slots: private: SMESHGUI_GenericHypothesisCreator* myCreator; QVBoxLayout* myLayout; - QLabel *myIconLabel, *myTypeLabel; + QLabel* myIconLabel; + QLabel* myTypeLabel; QString myHelpFileName; }; diff --git a/src/SMESHGUI/SMESHGUI_HypothesesUtils.cxx b/src/SMESHGUI/SMESHGUI_HypothesesUtils.cxx index 114b8dbc3..4be1a4cbb 100644 --- a/src/SMESHGUI/SMESHGUI_HypothesesUtils.cxx +++ b/src/SMESHGUI/SMESHGUI_HypothesesUtils.cxx @@ -388,30 +388,21 @@ namespace SMESH{ const bool isAlgo) { if(MYDEBUG) MESSAGE("Create " << aHypType << " with name " << aHypName); - - SMESH::SMESH_Hypothesis_var Hyp; - HypothesisData* aHypData = GetHypothesisData(aHypType); QString aServLib = aHypData->ServerLibName; - try { - Hyp = SMESHGUI::GetSMESHGen()->CreateHypothesis(aHypType, aServLib); - if (!Hyp->_is_nil()) { - _PTR(SObject) SHyp = SMESH::FindSObject(Hyp.in()); - if (SHyp) { - //if (strcmp(aHypName,"") != 0) + SMESH::SMESH_Hypothesis_var aHypothesis; + aHypothesis = SMESHGUI::GetSMESHGen()->CreateHypothesis(aHypType, aServLib); + if (!aHypothesis->_is_nil()) { + _PTR(SObject) aHypSObject = SMESH::FindSObject(aHypothesis.in()); + if (aHypSObject) { if (strlen(aHypName) > 0) - SMESH::SetName(SHyp, aHypName); - //SalomeApp_Application* app = - // dynamic_cast(SUIT_Session::session()->activeApplication()); - //if (app) - // app->objectBrowser()->updateTree(); - SMESHGUI::GetSMESHGUI()->updateObjBrowser(); - return Hyp._retn(); + SMESH::SetName(aHypSObject, aHypName); + SMESHGUI::GetSMESHGUI()->updateObjBrowser(); + return aHypothesis._retn(); } } - } - catch (const SALOME::SALOME_Exception & S_ex) { + } catch (const SALOME::SALOME_Exception & S_ex) { SalomeApp_Tools::QtCatchCorbaException(S_ex); } @@ -621,6 +612,7 @@ namespace SMESH{ CASE2MESSAGE( HYP_MISSING ); CASE2MESSAGE( HYP_NOTCONFORM ); CASE2MESSAGE( HYP_BAD_PARAMETER ); + CASE2MESSAGE( HYP_BAD_GEOMETRY ); default: continue; } // apply args to message: diff --git a/src/SMESHGUI/SMESHGUI_MakeNodeAtPointDlg.cxx b/src/SMESHGUI/SMESHGUI_MakeNodeAtPointDlg.cxx index b21ad3260..22cbb7293 100644 --- a/src/SMESHGUI/SMESHGUI_MakeNodeAtPointDlg.cxx +++ b/src/SMESHGUI/SMESHGUI_MakeNodeAtPointDlg.cxx @@ -138,16 +138,18 @@ QFrame* SMESHGUI_MakeNodeAtPointDlg::createMainFrame (QWidget* theParent) myX = new SMESHGUI_SpinBox(aCoordGrp); QLabel* aYLabel = new QLabel(tr("SMESH_Y"), aCoordGrp); - aYLabel->setAlignment( Qt::AlignRight | Qt::AlignVCenter | Qt::ExpandTabs ); + //aYLabel->setAlignment( Qt::AlignRight | Qt::AlignVCenter | Qt::ExpandTabs ); + aYLabel->setSizePolicy( QSizePolicy( QSizePolicy::Fixed, QSizePolicy::Fixed ) ); myY = new SMESHGUI_SpinBox(aCoordGrp); QLabel* aZLabel = new QLabel(tr("SMESH_Z"), aCoordGrp); - aZLabel->setAlignment( Qt::AlignRight | Qt::AlignVCenter | Qt::ExpandTabs ); + //aZLabel->setAlignment( Qt::AlignRight | Qt::AlignVCenter | Qt::ExpandTabs ); + aZLabel->setSizePolicy( QSizePolicy( QSizePolicy::Fixed, QSizePolicy::Fixed ) ); myZ = new SMESHGUI_SpinBox(aCoordGrp); - myX->RangeStepAndValidator(COORD_MIN, COORD_MAX, 10.0, 3); - myY->RangeStepAndValidator(COORD_MIN, COORD_MAX, 10.0, 3); - myZ->RangeStepAndValidator(COORD_MIN, COORD_MAX, 10.0, 3); + myX->RangeStepAndValidator(COORD_MIN, COORD_MAX, 10.0, DBL_DIGITS_DISPLAY); + myY->RangeStepAndValidator(COORD_MIN, COORD_MAX, 10.0, DBL_DIGITS_DISPLAY); + myZ->RangeStepAndValidator(COORD_MIN, COORD_MAX, 10.0, DBL_DIGITS_DISPLAY); // Method selection diff --git a/src/SMESHGUI/SMESHGUI_MeshOp.cxx b/src/SMESHGUI/SMESHGUI_MeshOp.cxx index 9aa469e68..ca82f9dd3 100644 --- a/src/SMESHGUI/SMESHGUI_MeshOp.cxx +++ b/src/SMESHGUI/SMESHGUI_MeshOp.cxx @@ -693,7 +693,6 @@ void SMESHGUI_MeshOp::availableHyps( const int theDim, * \param theHypType - specifies whether algorims or hypotheses or additional ones * are retrieved (possible values are in HypType enumeration) * \param theFather - start object for finding ( may be component, mesh, or sub-mesh ) - * \param theDataList - output list of hypotheses data * \param theHyps - output list of names. * \param theHypVars - output list of variables. * \param theAlgoData - to select hypos able to be used by this algo (optional) @@ -706,12 +705,12 @@ void SMESHGUI_MeshOp::existingHyps( const int theDim, const int theHypType, _PTR(SObject) theFather, QStringList& theHyps, - QValueList& theHypVars, + THypList& theHypList, HypothesisData* theAlgoData) { // Clear hypoheses list theHyps.clear(); - theHypVars.clear(); + theHypList.clear(); if ( !theFather ) return; @@ -754,15 +753,15 @@ void SMESHGUI_MeshOp::existingHyps( const int theDim, SMESH::SMESH_Hypothesis_var aHypVar = SMESH::SMESH_Hypothesis::_narrow( aVar ); if ( !aHypVar->_is_nil() ) { - QString aHypType( aHypVar->GetName() ); + CORBA::String_var aHypType( aHypVar->GetName() ); HypothesisData* aData = SMESH::GetHypothesisData( aHypType ); if ( ( theDim == -1 || aData->Dim.contains( theDim ) ) && ( isCompatible ( theAlgoData, aData, theHypType )) && ( isAux == aData->IsAux )) { - //theDataList.append( aData ); - theHyps.append( aName->Value().c_str() ); - theHypVars.append( aHypVar ); + std::string aHypName = aName->Value(); + theHyps.append( aHypName.c_str() ); + theHypList.append( THypItem( aHypVar, aHypName.c_str() ) ); } } } @@ -884,6 +883,19 @@ void SMESHGUI_MeshOp::onCreateHyp( const int theHypType, const int theIndex ) * \param theTypeName - specifies hypothesis to be created */ //================================================================================ +namespace +{ + QString GetUniqueName (const QStringList& theHypNames, + const QString& theName, + size_t theIteration = 1) + { + QString aName = theName + "_" + QString::number( theIteration ); + if ( theHypNames.contains( aName ) ) + return GetUniqueName( theHypNames, theName, ++theIteration ); + return aName; + } +} + void SMESHGUI_MeshOp::createHypothesis (const int theDim, const int theType, const QString& theTypeName) @@ -896,13 +908,30 @@ void SMESHGUI_MeshOp::createHypothesis (const int theDim, if (!aData) return; + QStringList aHypNames; + TDim2Type2HypList::const_iterator aDimIter = myExistingHyps.begin(); + for( ; aDimIter != myExistingHyps.end(); aDimIter++ ) { + const TType2HypList& aType2HypList = aDimIter.data(); + TType2HypList::const_iterator aTypeIter = aType2HypList.begin(); + for( ; aTypeIter != aType2HypList.end(); aTypeIter++ ) { + const THypList& aHypList = aTypeIter.data(); + THypList::const_iterator anIter = aHypList.begin(); + for( ; anIter != aHypList.end(); anIter++ ) { + const THypItem& aHypItem = *anIter; + const QString& aHypName = aHypItem.second; + aHypNames.append(aHypName); + } + } + } + QString aHypName = GetUniqueName( aHypNames, aData->Label); + // existing hypos int nbHyp = myExistingHyps[theDim][theType].count(); QString aClientLibName = aData->ClientLibName; if (aClientLibName == "") { // Call hypothesis creation server method (without GUI) - SMESH::CreateHypothesis(theTypeName, aData->Label, false); + SMESH::CreateHypothesis(theTypeName, aHypName, false); } else { // Get hypotheses creator client (GUI) SMESHGUI_GenericHypothesisCreator* aCreator = SMESH::GetHypothesisCreator(theTypeName); @@ -914,10 +943,10 @@ void SMESHGUI_MeshOp::createHypothesis (const int theDim, SMESH::SMESH_Hypothesis_var initParamHyp = getInitParamsHypothesis(theTypeName, aData->ServerLibName); myDlg->setEnabled( false ); - aCreator->create(initParamHyp, myDlg); + aCreator->create(initParamHyp, aHypName, myDlg); myDlg->setEnabled( true ); } else { - SMESH::CreateHypothesis(theTypeName, aData->Label, false); + SMESH::CreateHypothesis(theTypeName, aHypName, false); } } @@ -949,18 +978,19 @@ void SMESHGUI_MeshOp::onEditHyp( const int theHypType, const int theIndex ) if (aDim == -1) return; - QValueList aList = myExistingHyps[ aDim ][ theHypType ]; + const THypList& aList = myExistingHyps[ aDim ][ theHypType ]; if ( theIndex < 0 || theIndex >= aList.count() ) return; - SMESH::SMESH_Hypothesis_var aHyp = aList[ theIndex ]; + const THypItem& aHypItem = aList[ theIndex ]; + SMESH::SMESH_Hypothesis_var aHyp = aHypItem.first; if ( aHyp->_is_nil() ) return; - char* aTypeName = aHyp->GetName(); + CORBA::String_var aTypeName = aHyp->GetName(); SMESHGUI_GenericHypothesisCreator* aCreator = SMESH::GetHypothesisCreator( aTypeName ); if ( aCreator ) { myDlg->setEnabled( false ); - aCreator->edit( aHyp.in(), dlg() ); + aCreator->edit( aHyp.in(), aHypItem.second, dlg() ); myDlg->setEnabled( true ); } } @@ -1093,17 +1123,18 @@ void SMESHGUI_MeshOp::onAlgoSelected( const int theIndex, SMESH::SMESH_Hypothesis_var curHyp; if ( hypIndex >= 0 && hypIndex < myExistingHyps[ dim ][ type ].count() ) - curHyp = myExistingHyps[ dim ][ type ][ hypIndex ]; + curHyp = myExistingHyps[ dim ][ type ][ hypIndex ].first; if ( !myToCreate && !curAlgo && !curHyp->_is_nil() ) { // edition, algo not selected // try to find algo by selected hypothesis in order to keep it selected bool algoDeselectedByUser = ( theDim < 0 && aDim == dim ); - QString curHypType = curHyp->GetName(); + CORBA::String_var curHypType = curHyp->GetName(); if ( !algoDeselectedByUser && myObjHyps[ dim ][ type ].count() > 0 && - curHypType == myObjHyps[ dim ][ type ][ 0 ]->GetName()) + curHypType == myObjHyps[ dim ][ type ].first().first->GetName()) { - HypothesisData* hypData = SMESH::GetHypothesisData( curHyp->GetName() ); + CORBA::String_var aName = curHyp->GetName(); + HypothesisData* hypData = SMESH::GetHypothesisData( aName ); for ( int i = 0 ; i < myAvailableHypData[ dim ][ Algo ].count(); ++i ) { curAlgo = myAvailableHypData[ dim ][ Algo ][ i ]; if ( curAlgo && hypData && isCompatible( curAlgo, hypData, type )) @@ -1118,7 +1149,8 @@ void SMESHGUI_MeshOp::onAlgoSelected( const int theIndex, { // check if a selected hyp is compatible with the curAlgo if ( !curHyp->_is_nil() ) { - HypothesisData* hypData = SMESH::GetHypothesisData( curHyp->GetName() ); + CORBA::String_var aName = curHyp->GetName(); + HypothesisData* hypData = SMESH::GetHypothesisData( aName ); if ( !isCompatible( curAlgo, hypData, type )) curHyp = SMESH::SMESH_Hypothesis::_nil(); } @@ -1136,10 +1168,10 @@ void SMESHGUI_MeshOp::onAlgoSelected( const int theIndex, hypIndex = -1; if ( !isSubmesh && hypIndex < 0 && anExisting.count() == 1 ) { // none is yet selected => select the sole existing if it is not optional - QString hypTypeName = myExistingHyps[ dim ][ type ][ 0 ]->GetName(); + CORBA::String_var hypTypeName = myExistingHyps[ dim ][ type ].first().first->GetName(); bool isOptional = true; if ( algoByDim[ dim ] && - SMESH::IsAvailableHypothesis( algoByDim[ dim ], hypTypeName, isOptional ) && + SMESH::IsAvailableHypothesis( algoByDim[ dim ], hypTypeName.in(), isOptional ) && !isOptional ) hypIndex = 0; } @@ -1251,7 +1283,7 @@ bool SMESHGUI_MeshOp::createMesh( QString& theMess ) for ( int aHypType = MainHyp; aHypType <= AddHyp; aHypType++ ) { int aHypIndex = currentHyp( aDim, aHypType ); if ( aHypIndex >= 0 && aHypIndex < myExistingHyps[ aDim ][ aHypType ].count() ) { - SMESH::SMESH_Hypothesis_var aHypVar = myExistingHyps[ aDim ][ aHypType ][ aHypIndex ]; + SMESH::SMESH_Hypothesis_var aHypVar = myExistingHyps[ aDim ][ aHypType ][ aHypIndex ].first; if ( !aHypVar->_is_nil() ) SMESH::AddHypothesisOnMesh( aMeshVar, aHypVar ); } @@ -1379,7 +1411,7 @@ bool SMESHGUI_MeshOp::createSubMesh( QString& theMess ) if ( aHypIndex >= 0 && aHypIndex < myExistingHyps[ aDim ][ aHypType ].count() ) { SMESH::SMESH_Hypothesis_var aHypVar = - myExistingHyps[ aDim ][ aHypType ][ aHypIndex ]; + myExistingHyps[ aDim ][ aHypType ][ aHypIndex ].first; if ( !aHypVar->_is_nil() ) SMESH::AddHypothesisOnSubMesh( aSubMeshVar, aHypVar ); } @@ -1493,12 +1525,13 @@ SMESH::SMESH_Hypothesis_var SMESHGUI_MeshOp::getAlgo( const int theDim ) existingHyps( theDim, Algo, pObj, tmp, myExistingHyps[ theDim ][ Algo ]); // look for anexisting algo of such a type - QValueList& aHypVarList = myExistingHyps[ theDim ][ Algo ]; - QValueList::iterator anIter; - for ( anIter = aHypVarList.begin(); anIter != aHypVarList.end(); anIter++ ) + THypList& aHypVarList = myExistingHyps[ theDim ][ Algo ]; + THypList::iterator anIter = aHypVarList.begin(); + for ( ; anIter != aHypVarList.end(); anIter++ ) { - SMESH::SMESH_Hypothesis_var aHypVar = *anIter; - if ( !aHypVar->_is_nil() && aHypName == aHypVar->GetName() ) + SMESH::SMESH_Hypothesis_var aHypVar = (*anIter).first; + CORBA::String_var aName = aHypVar->GetName(); + if ( !aHypVar->_is_nil() && aHypName == aName ) { anAlgoVar = aHypVar; break; @@ -1518,7 +1551,7 @@ SMESH::SMESH_Hypothesis_var SMESHGUI_MeshOp::getAlgo( const int theDim ) // Create algorithm if (aCreator) - aCreator->create(true, myDlg); + aCreator->create(true, aHypName, myDlg); else SMESH::CreateHypothesis(aHypName, aHypData->Label, true); } @@ -1527,11 +1560,12 @@ SMESH::SMESH_Hypothesis_var SMESHGUI_MeshOp::getAlgo( const int theDim ) existingHyps( theDim, Algo, aFather, tmpList, myExistingHyps[ theDim ][ Algo ] ); } - QValueList& aNewHypVarList = myExistingHyps[ theDim ][ Algo ]; + THypList& aNewHypVarList = myExistingHyps[ theDim ][ Algo ]; for ( anIter = aNewHypVarList.begin(); anIter != aNewHypVarList.end(); ++anIter ) { - SMESH::SMESH_Hypothesis_var aHypVar = *anIter; - if ( !aHypVar->_is_nil() && aHypName == aHypVar->GetName() ) + SMESH::SMESH_Hypothesis_var aHypVar = (*anIter).first; + CORBA::String_var aName = aHypVar->GetName(); + if ( !aHypVar->_is_nil() && aHypName == aName ) { anAlgoVar = aHypVar; break; @@ -1590,8 +1624,8 @@ void SMESHGUI_MeshOp::readMesh() int aHypIndex = -1; if ( myObjHyps[ dim ][ Algo ].count() > 0 ) { - SMESH::SMESH_Hypothesis_var aVar = myObjHyps[ dim ][ Algo ].first(); - QString aHypTypeName = aVar->GetName(); + SMESH::SMESH_Hypothesis_var aVar = myObjHyps[ dim ][ Algo ].first().first; + CORBA::String_var aHypTypeName = aVar->GetName(); HypothesisData* algoData = SMESH::GetHypothesisData( aHypTypeName ); aHypIndex = myAvailableHypData[ dim ][ Algo ].findIndex ( algoData ); // if ( aHypIndex < 0 && algoData ) { @@ -1616,7 +1650,7 @@ void SMESHGUI_MeshOp::readMesh() // find index of requered hypothesis among existing ones for this dimension and type int aHypIndex = -1; if ( myObjHyps[ dim ][ hypType ].count() > 0 ) { - aHypIndex = find( myObjHyps[ dim ][ hypType ].first(), + aHypIndex = find( myObjHyps[ dim ][ hypType ].first().first, myExistingHyps[ dim ][ hypType ] ); if ( aHypIndex < 0 ) { // assigned hypothesis is incompatible with the algorithm @@ -1673,16 +1707,16 @@ QString SMESHGUI_MeshOp::name( _PTR(SObject) theSO ) const */ //================================================================================ int SMESHGUI_MeshOp::find( const SMESH::SMESH_Hypothesis_var& theHyp, - const QValueList& theHypList ) const + const THypList& theHypList ) const { int aRes = -1; if ( !theHyp->_is_nil() ) { int i = 0; - QValueList::const_iterator anIter; - for ( anIter = theHypList.begin(); anIter != theHypList.end(); ++ anIter ) + THypList::const_iterator anIter = theHypList.begin(); + for ( ; anIter != theHypList.end(); ++ anIter ) { - if ( theHyp->_is_equivalent( *anIter ) ) + if ( theHyp->_is_equivalent( (*anIter).first ) ) { aRes = i; break; @@ -1718,20 +1752,23 @@ bool SMESHGUI_MeshOp::editMeshOrSubMesh( QString& theMess ) SUIT_OverrideCursor aWaitCursor; // Set new name - SMESH::SetName( pObj, myDlg->objectText( SMESHGUI_MeshDlg::Obj ).latin1() ); + QString aName = myDlg->objectText( SMESHGUI_MeshDlg::Obj ); + SMESH::SetName( pObj, aName.latin1() ); // First, remove old algos in order to avoid messages on algorithm hiding for ( int dim = SMESH::DIM_0D; dim <= SMESH::DIM_3D; dim++ ) { if ( isAccessibleDim( dim ) && myObjHyps[ dim ][ Algo ].count() > 0 ) { - SMESH::SMESH_Hypothesis_var anOldAlgo = myObjHyps[ dim ][ Algo ].first(); + SMESH::SMESH_Hypothesis_var anOldAlgo = myObjHyps[ dim ][ Algo ].first().first; + CORBA::String_var anOldName = anOldAlgo->GetName(); SMESH::SMESH_Hypothesis_var anAlgoVar = getAlgo( dim ); + CORBA::String_var anAlgoName = anAlgoVar->GetName(); if ( anAlgoVar->_is_nil() || // no new algo selected or - strcmp(anOldAlgo->GetName(), anAlgoVar->GetName()) ) // algo change + strcmp(anOldName.in(), anAlgoName.in()) ) // algo change { // remove old algorithm - SMESH::RemoveHypothesisOrAlgorithmOnMesh ( pObj, myObjHyps[ dim ][ Algo ].first() ); + SMESH::RemoveHypothesisOrAlgorithmOnMesh ( pObj, myObjHyps[ dim ][ Algo ].first().first ); myObjHyps[ dim ][ Algo ].clear(); } } @@ -1749,8 +1786,9 @@ bool SMESHGUI_MeshOp::editMeshOrSubMesh( QString& theMess ) if ( !anAlgoVar->_is_nil() && // some algo selected and myObjHyps[ dim ][ Algo ].count() == 0 ) // no algo assigned { - SMESH::SMESH_Mesh_var aMeshVar = - SMESH::SMESH_Mesh::_narrow( _CAST(SObject,pObj)->GetObject() ); + SALOMEDS_SObject* aSObject = _CAST(SObject, pObj); + CORBA::Object_var anObject = aSObject->GetObject(); + SMESH::SMESH_Mesh_var aMeshVar = SMESH::SMESH_Mesh::_narrow( anObject ); bool isMesh = !aMeshVar->_is_nil(); if ( isMesh ) { SMESH::AddHypothesisOnMesh( aMeshVar, anAlgoVar ); @@ -1760,7 +1798,7 @@ bool SMESHGUI_MeshOp::editMeshOrSubMesh( QString& theMess ) if ( !aVar->_is_nil() ) SMESH::AddHypothesisOnSubMesh( aVar, anAlgoVar ); } - myObjHyps[ dim ][ Algo ].append( anAlgoVar ); + myObjHyps[ dim ][ Algo ].append( THypItem( anAlgoVar, aName) ); } // assign hypotheses @@ -1772,13 +1810,13 @@ bool SMESHGUI_MeshOp::editMeshOrSubMesh( QString& theMess ) // remove old hypotheses if ( myObjHyps[ dim ][ hypType ].count() > 0 ) { - anOldHypIndex = find( myObjHyps[ dim ][ hypType ].first(), + anOldHypIndex = find( myObjHyps[ dim ][ hypType ].first().first , myExistingHyps[ dim ][ hypType ] ); if ( aNewHypIndex != anOldHypIndex || // different hyps anOldHypIndex == -1 ) // hyps of different algos { SMESH::RemoveHypothesisOrAlgorithmOnMesh - ( pObj, myObjHyps[ dim ][ hypType ].first() ); + ( pObj, myObjHyps[ dim ][ hypType ].first().first ); myObjHyps[ dim ][ hypType ].clear(); } } @@ -1792,7 +1830,7 @@ bool SMESHGUI_MeshOp::editMeshOrSubMesh( QString& theMess ) if ( isMesh ) { SMESH::AddHypothesisOnMesh - (aMeshVar, myExistingHyps[ dim ][ hypType ][ aNewHypIndex ] ); + (aMeshVar, myExistingHyps[ dim ][ hypType ][ aNewHypIndex ].first ); } else { @@ -1800,7 +1838,7 @@ bool SMESHGUI_MeshOp::editMeshOrSubMesh( QString& theMess ) SMESH::SMESH_subMesh::_narrow( _CAST(SObject,pObj)->GetObject() ); if ( !aVar->_is_nil() ) SMESH::AddHypothesisOnSubMesh - ( aVar, myExistingHyps[ dim ][ hypType ][ aNewHypIndex ] ); + ( aVar, myExistingHyps[ dim ][ hypType ][ aNewHypIndex ].first ); } } // reread all hypotheses of mesh if necessary diff --git a/src/SMESHGUI/SMESHGUI_MeshOp.h b/src/SMESHGUI/SMESHGUI_MeshOp.h index 190c386dd..23365fd1a 100644 --- a/src/SMESHGUI/SMESHGUI_MeshOp.h +++ b/src/SMESHGUI/SMESHGUI_MeshOp.h @@ -35,12 +35,13 @@ #include "SMESH_SMESHGUI.hxx" #include "SMESHGUI_SelectionOp.h" -#include #include #include CORBA_SERVER_HEADER(GEOM_Gen) #include CORBA_SERVER_HEADER(SMESH_Mesh) +#include + class SMESHGUI_MeshDlg; class SMESHGUI_ShapeByMeshOp; class HypothesisData; @@ -58,6 +59,15 @@ public: enum HypType{ Algo = 0, MainHyp, AddHyp, NbHypTypes }; + typedef std::pair THypItem; + typedef QValueList< THypItem > THypList; + + typedef int THypType; + typedef QMap< THypType, THypList > TType2HypList; + + typedef int THypDim; + typedef QMap< THypDim, TType2HypList > TDim2Type2HypList; + SMESHGUI_MeshOp( const bool theToCreate, const bool theIsMesh = true ); virtual ~SMESHGUI_MeshOp(); @@ -94,7 +104,7 @@ private: const int theHypType, _PTR(SObject) theFather, QStringList& theHyps, - QValueList& theHypVars, + THypList& theHypList, HypothesisData* theAlgoData = 0); HypothesisData* hypData( const int theDim, const int theHypType, @@ -115,7 +125,7 @@ private: void readMesh(); QString name( _PTR(SObject) ) const; int find( const SMESH::SMESH_Hypothesis_var&, - const QValueList& ) const; + const THypList& theHypList) const; SMESH::SMESH_Hypothesis_var getInitParamsHypothesis( const QString& aHypType, const QString& aServerLib ) const; bool isSubshapeOk() const; @@ -123,16 +133,13 @@ private: void selectObject( _PTR(SObject) ) const; private: - typedef QMap< int, QValueList > IdToHypListMap; - typedef QMap< int, IdToHypListMap > DimToHypMap; - SMESHGUI_MeshDlg* myDlg; SMESHGUI_ShapeByMeshOp* myShapeByMeshOp; bool myToCreate; bool myIsMesh; - DimToHypMap myExistingHyps; //!< all hypothesis of SMESH module - DimToHypMap myObjHyps; //!< hypothesis assigned to the current + TDim2Type2HypList myExistingHyps; //!< all hypothesis of SMESH module + TDim2Type2HypList myObjHyps; //!< hypothesis assigned to the current // edited mesh/sub-mesh // hypdata corresponding to hypotheses present in myDlg diff --git a/src/SMESHGUI/SMESHGUI_MoveNodesDlg.cxx b/src/SMESHGUI/SMESHGUI_MoveNodesDlg.cxx index 8eb5e67ce..2c69a8161 100644 --- a/src/SMESHGUI/SMESHGUI_MoveNodesDlg.cxx +++ b/src/SMESHGUI/SMESHGUI_MoveNodesDlg.cxx @@ -184,16 +184,18 @@ QFrame* SMESHGUI_MoveNodesDlg::createMainFrame (QWidget* theParent) myX = new SMESHGUI_SpinBox(aCoordGrp); QLabel* aYLabel = new QLabel(tr("SMESH_Y"), aCoordGrp); - aYLabel->setAlignment( Qt::AlignRight | Qt::AlignVCenter | Qt::ExpandTabs ); + //aYLabel->setAlignment( Qt::AlignRight | Qt::AlignVCenter | Qt::ExpandTabs ); + aYLabel->setSizePolicy( QSizePolicy( QSizePolicy::Fixed, QSizePolicy::Fixed ) ); myY = new SMESHGUI_SpinBox(aCoordGrp); QLabel* aZLabel = new QLabel(tr("SMESH_Z"), aCoordGrp); - aZLabel->setAlignment( Qt::AlignRight | Qt::AlignVCenter | Qt::ExpandTabs ); + //aZLabel->setAlignment( Qt::AlignRight | Qt::AlignVCenter | Qt::ExpandTabs ); + aZLabel->setSizePolicy( QSizePolicy( QSizePolicy::Fixed, QSizePolicy::Fixed ) ); myZ = new SMESHGUI_SpinBox(aCoordGrp); - myX->RangeStepAndValidator(COORD_MIN, COORD_MAX, 25.0, 3); - myY->RangeStepAndValidator(COORD_MIN, COORD_MAX, 25.0, 3); - myZ->RangeStepAndValidator(COORD_MIN, COORD_MAX, 25.0, 3); + myX->RangeStepAndValidator(COORD_MIN, COORD_MAX, 25.0, DBL_DIGITS_DISPLAY); + myY->RangeStepAndValidator(COORD_MIN, COORD_MAX, 25.0, DBL_DIGITS_DISPLAY); + myZ->RangeStepAndValidator(COORD_MIN, COORD_MAX, 25.0, DBL_DIGITS_DISPLAY); QVBoxLayout* aLay = new QVBoxLayout(aFrame); aLay->addWidget(aPixGrp); diff --git a/src/SMESHGUI/SMESHGUI_NodesDlg.cxx b/src/SMESHGUI/SMESHGUI_NodesDlg.cxx index b89009898..357ee5889 100644 --- a/src/SMESHGUI/SMESHGUI_NodesDlg.cxx +++ b/src/SMESHGUI/SMESHGUI_NodesDlg.cxx @@ -310,17 +310,21 @@ SMESHGUI_NodesDlg::SMESHGUI_NodesDlg (SMESHGUI* theModule, GroupCoordinatesLayout->setAlignment(Qt::AlignTop); GroupCoordinatesLayout->setSpacing(6); GroupCoordinatesLayout->setMargin(11); + TextLabel_X = new QLabel(GroupCoordinates, "TextLabel_X"); TextLabel_X->setSizePolicy( QSizePolicy( QSizePolicy::Fixed, QSizePolicy::Fixed ) ); TextLabel_X->setText(tr("SMESH_X" )); GroupCoordinatesLayout->addWidget(TextLabel_X, 0, 0); + TextLabel_Y = new QLabel(GroupCoordinates, "TextLabel_Y"); - TextLabel_Y->setAlignment( Qt::AlignRight | Qt::AlignVCenter | Qt::ExpandTabs ); + //TextLabel_Y->setAlignment( Qt::AlignRight | Qt::AlignVCenter | Qt::ExpandTabs ); + TextLabel_Y->setSizePolicy( QSizePolicy( QSizePolicy::Fixed, QSizePolicy::Fixed ) ); TextLabel_Y->setText(tr("SMESH_Y" )); GroupCoordinatesLayout->addWidget(TextLabel_Y, 0, 2); TextLabel_Z = new QLabel(GroupCoordinates, "TextLabel_Z"); - TextLabel_Z->setAlignment( Qt::AlignRight | Qt::AlignVCenter | Qt::ExpandTabs ); + //TextLabel_Z->setAlignment( Qt::AlignRight | Qt::AlignVCenter | Qt::ExpandTabs ); + TextLabel_Z->setSizePolicy( QSizePolicy( QSizePolicy::Fixed, QSizePolicy::Fixed ) ); TextLabel_Z->setText(tr("SMESH_Z" )); GroupCoordinatesLayout->addWidget(TextLabel_Z, 0, 4); @@ -363,9 +367,9 @@ void SMESHGUI_NodesDlg::Init () step = 25.0; /* min, max, step and decimals for spin boxes */ - SpinBox_X->RangeStepAndValidator(COORD_MIN, COORD_MAX, step, 3); - SpinBox_Y->RangeStepAndValidator(COORD_MIN, COORD_MAX, step, 3); - SpinBox_Z->RangeStepAndValidator(COORD_MIN, COORD_MAX, step, 3); + SpinBox_X->RangeStepAndValidator(COORD_MIN, COORD_MAX, step, DBL_DIGITS_DISPLAY); + SpinBox_Y->RangeStepAndValidator(COORD_MIN, COORD_MAX, step, DBL_DIGITS_DISPLAY); + SpinBox_Z->RangeStepAndValidator(COORD_MIN, COORD_MAX, step, DBL_DIGITS_DISPLAY); SpinBox_X->SetValue(0.0); SpinBox_Y->SetValue(0.0); SpinBox_Z->SetValue(0.0); diff --git a/src/SMESHGUI/SMESHGUI_SpinBox.h b/src/SMESHGUI/SMESHGUI_SpinBox.h index cc5c99689..53069b718 100644 --- a/src/SMESHGUI/SMESHGUI_SpinBox.h +++ b/src/SMESHGUI/SMESHGUI_SpinBox.h @@ -36,6 +36,7 @@ // like in GEOM_SRC/src/DlgRef/DlgRef_SpinBox.h #define COORD_MIN -1e+15 #define COORD_MAX +1e+15 +#define DBL_DIGITS_DISPLAY 14 //================================================================================= // class : SMESHGUI_SpinBox diff --git a/src/SMESHGUI/SMESHGUI_TranslationDlg.cxx b/src/SMESHGUI/SMESHGUI_TranslationDlg.cxx index bf4fd6d98..c00e097d7 100644 --- a/src/SMESHGUI/SMESHGUI_TranslationDlg.cxx +++ b/src/SMESHGUI/SMESHGUI_TranslationDlg.cxx @@ -264,12 +264,12 @@ SMESHGUI_TranslationDlg::SMESHGUI_TranslationDlg( SMESHGUI* theModule, const cha SMESHGUI_TranslationDlgLayout->addWidget(GroupArguments, 1, 0); /* Initialisations */ - SpinBox1_1->RangeStepAndValidator(COORD_MIN, COORD_MAX, 10.0, 3); - SpinBox1_2->RangeStepAndValidator(COORD_MIN, COORD_MAX, 10.0, 3); - SpinBox1_3->RangeStepAndValidator(COORD_MIN, COORD_MAX, 10.0, 3); - SpinBox2_1->RangeStepAndValidator(COORD_MIN, COORD_MAX, 10.0, 3); - SpinBox2_2->RangeStepAndValidator(COORD_MIN, COORD_MAX, 10.0, 3); - SpinBox2_3->RangeStepAndValidator(COORD_MIN, COORD_MAX, 10.0, 3); + SpinBox1_1->RangeStepAndValidator(COORD_MIN, COORD_MAX, 10.0, DBL_DIGITS_DISPLAY); + SpinBox1_2->RangeStepAndValidator(COORD_MIN, COORD_MAX, 10.0, DBL_DIGITS_DISPLAY); + SpinBox1_3->RangeStepAndValidator(COORD_MIN, COORD_MAX, 10.0, DBL_DIGITS_DISPLAY); + SpinBox2_1->RangeStepAndValidator(COORD_MIN, COORD_MAX, 10.0, DBL_DIGITS_DISPLAY); + SpinBox2_2->RangeStepAndValidator(COORD_MIN, COORD_MAX, 10.0, DBL_DIGITS_DISPLAY); + SpinBox2_3->RangeStepAndValidator(COORD_MIN, COORD_MAX, 10.0, DBL_DIGITS_DISPLAY); GroupArguments->show(); RadioButton1->setChecked(TRUE); diff --git a/src/SMESHGUI/SMESH_msg_en.po b/src/SMESHGUI/SMESH_msg_en.po index 4ef2f345a..df115b105 100644 --- a/src/SMESHGUI/SMESH_msg_en.po +++ b/src/SMESHGUI/SMESH_msg_en.po @@ -1328,6 +1328,9 @@ msgstr "Hypothesis of %3 %2D algorithm \"%1\" has a bad parameter value" msgid "STATE_HYP_NOTCONFORM" msgstr "%3 %2D algorithm \"%1\" would produce not conform mesh: global \"Not Conform Mesh Allowed\" hypotesis is missing" +msgid "STATE_HYP_BAD_GEOMETRY" +msgstr "%3 %2D algorithm \"%1\" is assigned to geometry mismatching its expectation" + msgid "GLOBAL_ALGO" msgstr "Global" @@ -3407,6 +3410,9 @@ msgstr "Show SubShape" msgid "SMESHGUI_ComputeDlg::PUBLISH_SHAPE" msgstr "Publish SubShape" +msgid "SMESHGUI_ComputeDlg::MEMORY_LACK" +msgstr "Memory allocation problem" + msgid "COMPERR_OK" msgstr "No errors" diff --git a/src/SMESH_I/SMESH_2smeshpy.cxx b/src/SMESH_I/SMESH_2smeshpy.cxx index 3cd0dd18a..998266806 100644 --- a/src/SMESH_I/SMESH_2smeshpy.cxx +++ b/src/SMESH_I/SMESH_2smeshpy.cxx @@ -46,6 +46,7 @@ IMPLEMENT_STANDARD_HANDLE (_pyObject ,Standard_Transient); IMPLEMENT_STANDARD_HANDLE (_pyCommand ,Standard_Transient); IMPLEMENT_STANDARD_HANDLE (_pyGen ,_pyObject); IMPLEMENT_STANDARD_HANDLE (_pyMesh ,_pyObject); +IMPLEMENT_STANDARD_HANDLE (_pyMeshEditor ,_pyObject); IMPLEMENT_STANDARD_HANDLE (_pyHypothesis ,_pyObject); IMPLEMENT_STANDARD_HANDLE (_pyAlgorithm ,_pyHypothesis); IMPLEMENT_STANDARD_HANDLE (_pyComplexParamHypo,_pyHypothesis); @@ -55,6 +56,7 @@ IMPLEMENT_STANDARD_RTTIEXT(_pyObject ,Standard_Transient); IMPLEMENT_STANDARD_RTTIEXT(_pyCommand ,Standard_Transient); IMPLEMENT_STANDARD_RTTIEXT(_pyGen ,_pyObject); IMPLEMENT_STANDARD_RTTIEXT(_pyMesh ,_pyObject); +IMPLEMENT_STANDARD_RTTIEXT(_pyMeshEditor ,_pyObject); IMPLEMENT_STANDARD_RTTIEXT(_pyHypothesis ,_pyObject); IMPLEMENT_STANDARD_RTTIEXT(_pyAlgorithm ,_pyHypothesis); IMPLEMENT_STANDARD_RTTIEXT(_pyComplexParamHypo,_pyHypothesis); @@ -79,11 +81,39 @@ static TCollection_AsciiString theEmptyString; #undef DUMP_CONVERSION #endif +namespace { + + //================================================================================ + /*! + * \brief Set of TCollection_AsciiString initialized by C array of C strings + */ + //================================================================================ + + struct TStringSet: public set + { + /*! + * \brief Filling. The last string must be "" + */ + void Insert(const char* names[]) { + for ( int i = 0; names[i][0] ; ++i ) + insert( (char*) names[i] ); + } + /*! + * \brief Check if a string is in + */ + bool Contains(const TCollection_AsciiString& name ) { + return find( name ) != end(); + } + }; +} + //================================================================================ /*! * \brief Convert python script using commands of smesh.py * \param theScript - Input script * \retval TCollection_AsciiString - Convertion result + * + * Class SMESH_2smeshpy declared in SMESH_PythonDump.hxx */ //================================================================================ @@ -152,6 +182,17 @@ _pyGen::_pyGen(Resource_DataMapOfAsciiStringAsciiString& theEntry2AccessorMethod GetCreationCmd()->GetString() += "="; } +//================================================================================ +/*! + * \brief name of SMESH_Gen in smesh.py + */ +//================================================================================ + +const char* _pyGen::AccessorMethod() const +{ + return SMESH_2smeshpy::GenName(); +} + //================================================================================ /*! * \brief Convert a command using a specific converter @@ -182,9 +223,21 @@ Handle(_pyCommand) _pyGen::AddCommand( const TCollection_AsciiString& theCommand // SMESH_Mesh method? map< _pyID, Handle(_pyMesh) >::iterator id_mesh = myMeshes.find( objID ); if ( id_mesh != myMeshes.end() ) { + if ( aCommand->GetMethod() == "GetMeshEditor" ) { // MeshEditor creation + _pyID editorID = aCommand->GetResultValue(); + Handle(_pyMeshEditor) editor = new _pyMeshEditor( aCommand ); + myMeshEditors.insert( make_pair( editorID, editor )); + return aCommand; + } id_mesh->second->Process( aCommand ); return aCommand; } + // SMESH_MeshEditor method? + map< _pyID, Handle(_pyMeshEditor) >::iterator id_editor = myMeshEditors.find( objID ); + if ( id_editor != myMeshEditors.end() ) { + id_editor->second->Process( aCommand ); + return aCommand; + } // SMESH_Hypothesis method? list< Handle(_pyHypothesis) >::iterator hyp = myHypos.begin(); for ( ; hyp != myHypos.end(); ++hyp ) @@ -235,6 +288,7 @@ void _pyGen::Process( const Handle(_pyCommand)& theCommand ) // CreateHypothesis( theHypType, theLibName ) // Compute( mesh, geom ) + // mesh creation if ( theCommand->GetMethod() == "CreateMesh" || theCommand->GetMethod() == "CreateEmptyMesh" ) { @@ -272,14 +326,29 @@ void _pyGen::Process( const Handle(_pyCommand)& theCommand ) myHasPattern = true; } - // smeshgen.Method() --> smesh.smesh.Method() - theCommand->SetObject( SMESH_2smeshpy::GenName() ); - // Concatenate( [mesh1, ...], ... ) if ( theCommand->GetMethod() == "Concatenate" ) { AddMeshAccessorMethod( theCommand ); } + + // Replace name of SMESH_Gen + + // names of SMESH_Gen methods fully equal to methods defined in smesh.py + static TStringSet smeshpyMethods; + if ( smeshpyMethods.empty() ) { + const char * names[] = + { "SetEmbeddedMode","IsEmbeddedMode","SetCurrentStudy","GetCurrentStudy", + "GetPattern","GetSubShapesId", + "" }; // <- mark of array end + smeshpyMethods.Insert( names ); + } + if ( smeshpyMethods.Contains( theCommand->GetMethod() )) + // smeshgen.Method() --> smesh.Method() + theCommand->SetObject( SMESH_2smeshpy::SmeshpyName() ); + else + // smeshgen.Method() --> smesh.smesh.Method() + theCommand->SetObject( SMESH_2smeshpy::GenName() ); } //================================================================================ @@ -372,13 +441,13 @@ Handle(_pyHypothesis) _pyGen::FindHyp( const _pyID& theHypID ) //================================================================================ Handle(_pyHypothesis) _pyGen::FindAlgo( const _pyID& theGeom, const _pyID& theMesh, - const TCollection_AsciiString& theAlgoType ) + const Handle(_pyHypothesis)& theHypothesis ) { list< Handle(_pyHypothesis) >::iterator hyp = myHypos.begin(); for ( ; hyp != myHypos.end(); ++hyp ) if ( !hyp->IsNull() && (*hyp)->IsAlgo() && - (*hyp)->GetType() == theAlgoType && + theHypothesis->CanBeCreatedBy( (*hyp)->GetAlgoType() ) && (*hyp)->GetGeom() == theGeom && (*hyp)->GetMesh() == theMesh ) return *hyp; @@ -472,7 +541,7 @@ static bool sameGroupType( const _pyID& grpID, case GEOM::SOLID: case GEOM::SHELL: type = SMESH::VOLUME; break; case GEOM::COMPOUND: { - GEOM::GEOM_Gen_var aGeomGen = SMESH_Gen_i::GetSMESHGen()->GetGeomEngine(); + GEOM::GEOM_Gen_ptr aGeomGen = SMESH_Gen_i::GetSMESHGen()->GetGeomEngine(); if ( !aGeomGen->_is_nil() ) { GEOM::GEOM_IGroupOperations_var aGrpOp = aGeomGen->GetIGroupOperations( study->StudyId() ); @@ -535,7 +604,8 @@ _pyMesh::_pyMesh(const Handle(_pyCommand) theCreationCmd): void _pyMesh::Process( const Handle(_pyCommand)& theCommand ) { - // smesh.py wraps the following methods: + // some methods of SMESH_Mesh interface needs special conversion + // to methods of Mesh python class // // 1. GetSubMesh(geom, name) + AddHypothesis(geom, algo) // --> in Mesh_Algorithm.Create(mesh, geom, hypo, so) @@ -543,21 +613,16 @@ void _pyMesh::Process( const Handle(_pyCommand)& theCommand ) // --> in Mesh_Algorithm.Hypothesis(hyp, args, so) // 3. CreateGroupFromGEOM(type, name, grp) // --> in Mesh.Group(grp, name="") - // 4. ExportToMED(f, opt, version) - // --> in Mesh.ExportToMED( f, version, opt=0 ) - // 5. ExportMED(f, opt) - // --> in Mesh.ExportMED( f,opt=0 ) - // 6. ExportDAT(f) - // --> in Mesh.ExportDAT( f ) - // 7. ExportUNV(f) - // --> in Mesh.ExportUNV(f) - // 8. ExportSTL(f, ascii) - // --> in Mesh.ExportSTL(f, ascii=1) + // 4. ExportToMED(f, auto_groups, version) + // --> in Mesh.ExportMED( f, auto_groups, version ) + // 5. etc const TCollection_AsciiString method = theCommand->GetMethod(); + // ---------------------------------------------------------------------- if ( method == "GetSubMesh" ) { mySubmeshes.push_back( theCommand ); } + // ---------------------------------------------------------------------- else if ( method == "AddHypothesis" ) { // mesh.AddHypothesis(geom, HYPO ) myAddHypCmds.push_back( theCommand ); // set mesh to hypo @@ -569,6 +634,7 @@ void _pyMesh::Process( const Handle(_pyCommand)& theCommand ) hyp->SetMesh( this->GetID() ); } } + // ---------------------------------------------------------------------- else if ( method == "CreateGroupFromGEOM" ) {// (type, name, grp) _pyID grp = theCommand->GetArg( 3 ); if ( sameGroupType( grp, theCommand->GetArg( 1 )) ) { // --> Group(grp) @@ -580,16 +646,18 @@ void _pyMesh::Process( const Handle(_pyCommand)& theCommand ) AddMeshAccess( theCommand ); } } - else if ( method == "ExportToMED" ) {//(f, opt, version) - // --> (f, version, opt) - _pyID opt = theCommand->GetArg( 2 ); - _pyID ver = theCommand->GetArg( 3 ); - theCommand->SetArg( 2, ver ); - theCommand->SetArg( 3, opt ); + // ---------------------------------------------------------------------- + else if ( method == "ExportToMED" ) { // ExportToMED() --> ExportMED() + theCommand->SetMethod( "ExportMED" ); + } + // ---------------------------------------------------------------------- + else if ( method == "CreateGroup" ) { // CreateGroup() --> CreateEmptyGroup() + theCommand->SetMethod( "CreateEmptyGroup" ); } + // ---------------------------------------------------------------------- else if ( method == "RemoveHypothesis" ) // (geom, hyp) { - const _pyID & hypID = theCommand->GetArg( 2 ); + _pyID hypID = theCommand->GetArg( 2 ); // check if this mesh still has corresponding addition command bool hasAddCmd = false; @@ -609,62 +677,55 @@ void _pyMesh::Process( const Handle(_pyCommand)& theCommand ) } Handle(_pyHypothesis) hyp = theGen->FindHyp( hypID ); if ( ! hasAddCmd ) { // hypo addition already wrapped - // access to wrapped mesh - AddMeshAccess( theCommand ); - // access to wrapped algo - if ( !hyp.IsNull() && hyp->IsAlgo() && hyp->IsWrapped() ) - theCommand->SetArg( 2, theCommand->GetArg( 2 ) + ".GetAlgorithm()" ); + // RemoveHypothesis(geom, hyp) --> RemoveHypothesis( hyp, geom=0 ) + _pyID geom = theCommand->GetArg( 1 ); + theCommand->RemoveArgs(); + theCommand->SetArg( 1, hypID ); + if ( geom != GetGeom() ) + theCommand->SetArg( 2, geom ); } // remove hyp from myHypos myHypos.remove( hyp ); } - - // leave only one " mesh_editor_ = mesh.GetMeshEditor()" - else if ( theCommand->GetMethod() == "GetMeshEditor") - { - if ( myHasEditor ) - theCommand->Clear(); - else - AddMeshAccess( theCommand ); - myHasEditor = true; - } - - // apply theCommand to the mesh wrapped by smeshpy mesh + // add accessor method if necessary else { - AddMeshAccess( theCommand ); + if ( NeedMeshAccess( theCommand )) + // apply theCommand to the mesh wrapped by smeshpy mesh + AddMeshAccess( theCommand ); } } -namespace { - - //================================================================================ - /*! - * \brief add addition result treatement command - * \param addCmd - hypothesis addition command - */ - //================================================================================ +//================================================================================ +/*! + * \brief Return True if addition of accesor method is needed + */ +//================================================================================ - void addErrorTreatmentCmd( Handle(_pyCommand) & addCmd, - const bool isAlgo) - { - return; // TO DEBUD - TreatHypoStatus() is not placed right after addCmd - // addCmd: status = mesh.AddHypothesis( geom, hypo ) - // treatement command: - // def TreatHypoStatus(status, hypName, geomName, isAlgo): - TCollection_AsciiString status = addCmd->GetResultValue(); - if ( !status.IsEmpty() ) { - const _pyID& geomID = addCmd->GetArg( 1 ); - const _pyID& hypoID = addCmd->GetArg( 2 ); - TCollection_AsciiString cmdStr = addCmd->GetIndentation() + - SMESH_2smeshpy::SmeshpyName() + ".TreatHypoStatus( " + status + ", " + - SMESH_2smeshpy::SmeshpyName() + ".GetName(" + hypoID + "), " + - SMESH_2smeshpy::SmeshpyName() + ".GetName(" + geomID + "), " + - (char*)( isAlgo ? "True" : "False" ) + " )"; - Handle(_pyCommand) cmd = theGen->AddCommand( cmdStr ); - addCmd->AddDependantCmd( cmd, true ); - } - } +bool _pyMesh::NeedMeshAccess( const Handle(_pyCommand)& theCommand ) +{ + // names of SMESH_Mesh methods fully equal to methods of class Mesh, so + // no conversion is needed for them at all: + static TStringSet sameMethods; + if ( sameMethods.empty() ) { + const char * names[] = + { "ExportDAT","ExportUNV","ExportSTL", "RemoveGroup","RemoveGroupWithContents", + "GetGroups","UnionGroups","IntersectGroups","CutGroups","GetLog","GetId","ClearLog", + "GetStudyId","HasDuplicatedGroupNamesMED","GetMEDMesh","NbNodes","NbElements", + "NbEdges","NbEdgesOfOrder","NbFaces","NbFacesOfOrder","NbTriangles", + "NbTrianglesOfOrder","NbQuadrangles","NbQuadranglesOfOrder","NbPolygons","NbVolumes", + "NbVolumesOfOrder","NbTetras","NbTetrasOfOrder","NbHexas","NbHexasOfOrder", + "NbPyramids","NbPyramidsOfOrder","NbPrisms","NbPrismsOfOrder","NbPolyhedrons", + "NbSubMesh","GetElementsId","GetElementsByType","GetNodesId","GetElementType", + "GetSubMeshElementsId","GetSubMeshNodesId","GetSubMeshElementType","Dump","GetNodeXYZ", + "GetNodeInverseElements","GetShapeID","GetShapeIDForElem","GetElemNbNodes", + "GetElemNode","IsMediumNode","IsMediumNodeOfAnyElem","ElemNbEdges","ElemNbFaces", + "IsPoly","IsQuadratic","BaryCenter","GetHypothesisList", + "" }; // <- mark of end + sameMethods.Insert( names ); + } + + return !sameMethods.Contains( theCommand->GetMethod() ); } //================================================================================ @@ -682,19 +743,19 @@ void _pyMesh::Flush() for ( cmd = myAddHypCmds.begin(); cmd != myAddHypCmds.end(); ++cmd ) { Handle(_pyCommand) addCmd = *cmd; - const _pyID& algoID = addCmd->GetArg( 2 ); + _pyID algoID = addCmd->GetArg( 2 ); Handle(_pyHypothesis) algo = theGen->FindHyp( algoID ); if ( algo.IsNull() || !algo->IsAlgo() ) continue; // try to convert _pyID geom = addCmd->GetArg( 1 ); + bool isLocalAlgo = ( geom != GetGeom() ); if ( algo->Addition2Creation( addCmd, this->GetID() )) // OK { // wrapped algo is created atfer mesh creation GetCreationCmd()->AddDependantCmd( addCmd ); - if ( geom != GetGeom() ) // local algo - { + if ( isLocalAlgo ) { // mesh.AddHypothesis(geom, ALGO ) --> mesh.AlgoMethod(geom) addCmd->SetArg( addCmd->GetNbArgs() + 1, TCollection_AsciiString( "geom=" ) + geom ); @@ -709,15 +770,13 @@ void _pyMesh::Flush() } } } - else // ALGO was already created + else // KO - ALGO was already created { - // mesh.AddHypothesis(geom, ALGO ) --> mesh.GetMesh().AddHypothesis(geom, ALGO ) - AddMeshAccess( addCmd ); - // mesh.GetMesh().AddHypothesis(geom, ALGO ) -> - // mesh.GetMesh().AddHypothesis(geom, ALGO.GetAlgorithm() ) - addCmd->SetArg( 2, addCmd->GetArg( 2 ) + ".GetAlgorithm()" ); - // add addition result treatement cmd - addErrorTreatmentCmd( addCmd, true ); + // mesh.AddHypothesis(geom, ALGO) --> mesh.AddHypothesis(ALGO, geom=0) + addCmd->RemoveArgs(); + addCmd->SetArg( 1, algoID ); + if ( isLocalAlgo ) + addCmd->SetArg( 2, geom ); } } @@ -726,24 +785,27 @@ void _pyMesh::Flush() for ( cmd = myAddHypCmds.begin(); cmd != myAddHypCmds.end(); ++cmd ) { Handle(_pyCommand) addCmd = *cmd; - const _pyID& hypID = addCmd->GetArg( 2 ); + _pyID hypID = addCmd->GetArg( 2 ); Handle(_pyHypothesis) hyp = theGen->FindHyp( hypID ); if ( hyp.IsNull() || hyp->IsAlgo() ) continue; - if ( !hyp->Addition2Creation( addCmd, this->GetID() )) - { - AddMeshAccess( addCmd ); - // add addition result treatement cmd - addErrorTreatmentCmd( addCmd, false ); + bool converted = hyp->Addition2Creation( addCmd, this->GetID() ); + if ( !converted ) { + // mesh.AddHypothesis(geom, HYP) --> mesh.AddHypothesis(HYP, geom=0) + _pyID geom = addCmd->GetArg( 1 ); + addCmd->RemoveArgs(); + addCmd->SetArg( 1, hypID ); + if ( geom != GetGeom() ) + addCmd->SetArg( 2, geom ); } } // sm = mesh.GetSubMesh(geom, name) --> sm = mesh.GetMesh().GetSubMesh(geom, name) - for ( cmd = mySubmeshes.begin(); cmd != mySubmeshes.end(); ++cmd ) { - Handle(_pyCommand) subCmd = *cmd; - if ( subCmd->GetNbArgs() > 0 ) - AddMeshAccess( subCmd ); - } +// for ( cmd = mySubmeshes.begin(); cmd != mySubmeshes.end(); ++cmd ) { +// Handle(_pyCommand) subCmd = *cmd; +// if ( subCmd->GetNbArgs() > 0 ) +// AddMeshAccess( subCmd ); +// } myAddHypCmds.clear(); mySubmeshes.clear(); @@ -753,6 +815,61 @@ void _pyMesh::Flush() (*hyp)->Flush(); } +//================================================================================ +/*! + * \brief MeshEditor convert its commands to ones of mesh + */ +//================================================================================ + +_pyMeshEditor::_pyMeshEditor(const Handle(_pyCommand)& theCreationCmd): + _pyObject( theCreationCmd ) +{ + myMesh = theCreationCmd->GetObject(); + myCreationCmdStr = theCreationCmd->GetString(); + theCreationCmd->Clear(); +} + +//================================================================================ +/*! + * \brief convert its commands to ones of mesh + */ +//================================================================================ + +void _pyMeshEditor::Process( const Handle(_pyCommand)& theCommand) +{ + // names of SMESH_MeshEditor methods fully equal to methods of class Mesh, so + // commands calling this methods are converted to calls of methods of Mesh + static TStringSet sameMethods; + if ( sameMethods.empty() ) { + const char * names[] = { + "RemoveElements","RemoveNodes","AddNode","AddEdge","AddFace","AddPolygonalFace", + "AddVolume","AddPolyhedralVolume","AddPolyhedralVolumeByFaces","MoveNode", + "InverseDiag","DeleteDiag","Reorient","ReorientObject","SplitQuad","SplitQuadObject", + "BestSplit","Smooth","SmoothObject","SmoothParametric","SmoothParametricObject", + "ConvertToQuadratic","ConvertFromQuadratic","RenumberNodes","RenumberElements", + "RotationSweep","RotationSweepObject","ExtrusionSweep","AdvancedExtrusion", + "ExtrusionSweepObject","ExtrusionSweepObject1D","ExtrusionSweepObject2D","Mirror", + "MirrorObject","Translate","TranslateObject","Rotate","RotateObject", + "FindCoincidentNodes","FindCoincidentNodesOnPart","MergeNodes","FindEqualElements", + "MergeElements","MergeEqualElements","SewFreeBorders","SewConformFreeBorders", + "SewBorderToSide","SewSideElements","ChangeElemNodes","GetLastCreatedNodes", + "GetLastCreatedElems", + "" }; // <- mark of end + sameMethods.Insert( names ); + } + + if ( sameMethods.Contains( theCommand->GetMethod() )) { + theCommand->SetObject( myMesh ); + } + else { + // editor creation command is needed only if any editor function is called + if ( !myCreationCmdStr.IsEmpty() ) { + GetCreationCmd()->GetString() = myCreationCmdStr; + myCreationCmdStr.Clear(); + } + } +} + //================================================================================ /*! * \brief _pyHypothesis constructor @@ -855,25 +972,37 @@ Handle(_pyHypothesis) _pyHypothesis::NewHypothesis( const Handle(_pyCommand)& th hyp->AddArgMethod( "SetNumberOfSegments"); hyp->AddArgMethod( "SetPythonLog10RatioFunction"); } - // 2D ---------- - else if ( hypType == "MEFISTO_2D" ) { + // MEFISTO_2D ---------- + else if ( hypType == "MEFISTO_2D" ) { // MEFISTO_2D algo->SetConvMethodAndType( "Triangle", hypType.ToCString()); } else if ( hypType == "MaxElementArea" ) { hyp->SetConvMethodAndType( "MaxElementArea", "MEFISTO_2D"); + hyp->SetConvMethodAndType( "MaxElementArea", "NETGEN_2D_ONLY"); hyp->AddArgMethod( "SetMaxElementArea"); } else if ( hypType == "LengthFromEdges" ) { hyp->SetConvMethodAndType( "LengthFromEdges", "MEFISTO_2D"); + hyp->SetConvMethodAndType( "LengthFromEdges", "NETGEN_2D_ONLY"); } + // Quadrangle_2D ---------- else if ( hypType == "Quadrangle_2D" ) { algo->SetConvMethodAndType( "Quadrangle" , hypType.ToCString()); } else if ( hypType == "QuadranglePreference" ) { hyp->SetConvMethodAndType( "QuadranglePreference", "Quadrangle_2D"); - } - // 3D ---------- - else if ( hypType == "NETGEN_3D") { + hyp->SetConvMethodAndType( "QuadranglePreference", "NETGEN_2D_ONLY"); + } + // NETGEN ---------- +// else if ( hypType == "NETGEN_2D") { // 1D-2D +// algo->SetConvMethodAndType( "Triangle" , hypType.ToCString()); +// algo->myArgs.Append( "algo=smesh.NETGEN" ); +// } + else if ( hypType == "NETGEN_2D_ONLY") { // 2D + algo->SetConvMethodAndType( "Triangle" , hypType.ToCString()); + algo->myArgs.Append( "algo=smesh.NETGEN_2D" ); + } + else if ( hypType == "NETGEN_3D") { // 3D algo->SetConvMethodAndType( "Tetrahedron" , hypType.ToCString()); algo->myArgs.Append( "algo=smesh.NETGEN" ); } @@ -881,14 +1010,16 @@ Handle(_pyHypothesis) _pyHypothesis::NewHypothesis( const Handle(_pyCommand)& th hyp->SetConvMethodAndType( "MaxElementVolume", "NETGEN_3D"); hyp->AddArgMethod( "SetMaxElementVolume" ); } + // GHS3D_3D ---------- else if ( hypType == "GHS3D_3D" ) { algo->SetConvMethodAndType( "Tetrahedron", hypType.ToCString()); algo->myArgs.Append( "algo=smesh.GHS3D" ); } + // Hexa_3D --------- else if ( hypType == "Hexa_3D" ) { algo->SetConvMethodAndType( "Hexahedron", hypType.ToCString()); } - // Repetitive --------- + // Repetitive Projection_1D --------- else if ( hypType == "Projection_1D" ) { algo->SetConvMethodAndType( "Projection1D", hypType.ToCString()); } @@ -899,6 +1030,7 @@ Handle(_pyHypothesis) _pyHypothesis::NewHypothesis( const Handle(_pyCommand)& th // 2 args of SetVertexAssociation() will become the 3-th and 4-th args of hyp creation command hyp->AddArgMethod( "SetVertexAssociation", 2 ); } + // Projection_2D --------- else if ( hypType == "Projection_2D" ) { algo->SetConvMethodAndType( "Projection2D", hypType.ToCString()); } @@ -908,6 +1040,7 @@ Handle(_pyHypothesis) _pyHypothesis::NewHypothesis( const Handle(_pyCommand)& th hyp->AddArgMethod( "SetSourceMesh"); hyp->AddArgMethod( "SetVertexAssociation", 4 ); } + // Projection_3D --------- else if ( hypType == "Projection_3D" ) { algo->SetConvMethodAndType( "Projection3D", hypType.ToCString()); } @@ -917,9 +1050,11 @@ Handle(_pyHypothesis) _pyHypothesis::NewHypothesis( const Handle(_pyCommand)& th hyp->AddArgMethod( "SetSourceMesh"); hyp->AddArgMethod( "SetVertexAssociation", 4 ); } + // Prism_3D --------- else if ( hypType == "Prism_3D" ) { algo->SetConvMethodAndType( "Prism", hypType.ToCString()); } + // RadialPrism_3D --------- else if ( hypType == "RadialPrism_3D" ) { algo->SetConvMethodAndType( "Prism", hypType.ToCString()); } @@ -932,7 +1067,7 @@ Handle(_pyHypothesis) _pyHypothesis::NewHypothesis( const Handle(_pyCommand)& th hyp->SetConvMethodAndType( "LayerDistribution", "RadialPrism_3D"); } - if ( !algo->GetCreationMethod().IsEmpty() ) { + if ( algo->IsValid() ) { return algo; } return hyp; @@ -960,7 +1095,7 @@ bool _pyHypothesis::Addition2Creation( const Handle(_pyCommand)& theCmd, Handle(_pyHypothesis) algo; if ( !IsAlgo() ) { // find algo created on myGeom in theMesh - algo = theGen->FindAlgo( myGeom, theMesh, GetType() ); + algo = theGen->FindAlgo( myGeom, theMesh, this ); if ( algo.IsNull() ) return false; algo->GetCreationCmd()->AddDependantCmd( theCmd ); @@ -970,7 +1105,7 @@ bool _pyHypothesis::Addition2Creation( const Handle(_pyCommand)& theCmd, // mesh.AddHypothesis(geom,hyp) --> hyp = .myCreationMethod(args) theCmd->SetResultValue( GetID() ); theCmd->SetObject( IsAlgo() ? theMesh : algo->GetID()); - theCmd->SetMethod( myCreationMethod ); + theCmd->SetMethod( IsAlgo() ? GetAlgoCreationMethod() : GetCreationMethod( algo->GetAlgoType() )); // set args theCmd->RemoveArgs(); for ( int i = 1; i <= myArgs.Length(); ++i ) { @@ -1190,7 +1325,7 @@ bool _pyLayerDistributionHypo::Addition2Creation( const Handle(_pyCommand)& theA // Convert my creation => me = RadialPrismAlgo.Get3DHypothesis() // find RadialPrism algo created on for theMesh - Handle(_pyHypothesis) algo = theGen->FindAlgo( geom, theMesh, this->GetType() ); + Handle(_pyHypothesis) algo = theGen->FindAlgo( geom, theMesh, this ); if ( !algo.IsNull() ) { GetCreationCmd()->SetObject( algo->GetID() ); GetCreationCmd()->SetMethod( "Get3DHypothesis" ); @@ -1306,7 +1441,7 @@ bool _pySegmentLengthAroundVertexHyp::Addition2Creation( const Handle(_pyCommand while ( algo.IsNull() && !geom.IsEmpty()) { // try to find geom as a father of geom = FatherID( geom ); - algo = theGen->FindAlgo( geom, theMeshID, GetType() ); + algo = theGen->FindAlgo( geom, theMeshID, this ); } if ( algo.IsNull() ) return false; // also possible to find geom as brother of veretex... diff --git a/src/SMESH_I/SMESH_2smeshpy.hxx b/src/SMESH_I/SMESH_2smeshpy.hxx index 2f1bc027c..a09a84cd6 100644 --- a/src/SMESH_I/SMESH_2smeshpy.hxx +++ b/src/SMESH_I/SMESH_2smeshpy.hxx @@ -36,46 +36,23 @@ // =========================================================================================== /*! - * \brief Tool converting SMESH engine calls into commands defined in smesh.py - * * This file was created in order to respond to requirement of bug PAL10494: * SMESH python dump uses idl interface. * * The creation reason is that smesh.py commands defining hypotheses encapsulate * several SMESH engine method calls. As well, the dependencies between smesh.py - * classes differ from ones between SMESH IDL interfaces. + * classes differ from ones between corresponding SMESH IDL interfaces. * - * The only API method here is SMESH_2smeshpy::ConvertScript(), the rest ones are - * for internal usage + * Everything here is for internal usage by SMESH_2smeshpy::ConvertScript() + * declared in SMESH_PythonDump.hxx * - * See comments to _pyHypothesis class to know how to assure convertion of a new hypothesis + * See comments to _pyHypothesis class to know how to assure convertion of a new + * type of hypothesis */ // =========================================================================================== class Resource_DataMapOfAsciiStringAsciiString; -class SMESH_2smeshpy -{ -public: - /*! - * \brief Convert a python script using commands of smesh.py - * \param theScript - Input script - * \param theEntry2AccessorMethod - The returning method names to access to - * objects wrapped with python class - * \retval TCollection_AsciiString - Convertion result - */ - static TCollection_AsciiString - ConvertScript(const TCollection_AsciiString& theScript, - Resource_DataMapOfAsciiStringAsciiString& theEntry2AccessorMethod); - - /*! - * \brief Return the name of the python file wrapping IDL API - * \retval TCollection_AsciiString - The file name - */ - static char* SmeshpyName() { return "smesh"; } - static char* GenName() { return "smesh.smesh"; } -}; - // =========================================================================================== // ===================== // INTERNAL STUFF @@ -93,6 +70,7 @@ DEFINE_STANDARD_HANDLE (_pyCommand ,Standard_Transient); DEFINE_STANDARD_HANDLE (_pyObject ,Standard_Transient); DEFINE_STANDARD_HANDLE (_pyGen ,_pyObject); DEFINE_STANDARD_HANDLE (_pyMesh ,_pyObject); +DEFINE_STANDARD_HANDLE (_pyMeshEditor,_pyObject); DEFINE_STANDARD_HANDLE (_pyHypothesis,_pyObject); DEFINE_STANDARD_HANDLE (_pyAlgorithm ,_pyHypothesis); @@ -198,20 +176,21 @@ public: void Flush(); Handle(_pyHypothesis) FindHyp( const _pyID& theHypID ); Handle(_pyHypothesis) FindAlgo( const _pyID& theGeom, const _pyID& theMesh, - const TCollection_AsciiString& theAlgoType); + const Handle(_pyHypothesis)& theHypothesis); void ExchangeCommands( Handle(_pyCommand) theCmd1, Handle(_pyCommand) theCmd2 ); void SetCommandAfter( Handle(_pyCommand) theCmd, Handle(_pyCommand) theAfterCmd ); std::list< Handle(_pyCommand) >& GetCommands() { return myCommands; } void SetAccessorMethod(const _pyID& theID, const char* theMethod ); bool AddMeshAccessorMethod( Handle(_pyCommand) theCmd ) const; bool AddAlgoAccessorMethod( Handle(_pyCommand) theCmd ) const; - const char* AccessorMethod() const { return SMESH_2smeshpy::GenName(); } + const char* AccessorMethod() const; private: - std::map< _pyID, Handle(_pyMesh) > myMeshes; - std::list< Handle(_pyHypothesis) > myHypos; - std::list< Handle(_pyCommand) > myCommands; - int myNbCommands; - bool myHasPattern; + std::map< _pyID, Handle(_pyMesh) > myMeshes; + std::map< _pyID, Handle(_pyMeshEditor) > myMeshEditors; + std::list< Handle(_pyHypothesis) > myHypos; + std::list< Handle(_pyCommand) > myCommands; + int myNbCommands; + bool myHasPattern; Resource_DataMapOfAsciiStringAsciiString& myID2AccessorMethod; DEFINE_STANDARD_RTTI (_pyGen) @@ -236,6 +215,7 @@ public: void Flush(); const char* AccessorMethod() const { return _pyMesh_ACCESS_METHOD; } private: + static bool NeedMeshAccess( const Handle(_pyCommand)& theCommand ); static void AddMeshAccess( const Handle(_pyCommand)& theCommand ) { theCommand->SetObject( theCommand->GetObject() + "." _pyMesh_ACCESS_METHOD ); } @@ -243,20 +223,36 @@ private: }; #undef _pyMesh_ACCESS_METHOD +// ------------------------------------------------------------------------------------- +/*! + * \brief MeshEditor convert its commands to ones of mesh + */ +// ------------------------------------------------------------------------------------- +class _pyMeshEditor: public _pyObject +{ + _pyID myMesh; + TCollection_AsciiString myCreationCmdStr; +public: + _pyMeshEditor(const Handle(_pyCommand)& theCreationCmd); + void Process( const Handle(_pyCommand)& theCommand); + virtual void Flush() {} + + DEFINE_STANDARD_RTTI (_pyMesh) +}; + // ------------------------------------------------------------------------------------- /*! * \brief Root class for hypothesis * - * HOWTO assure convertion of a new hypothesis - * In NewHypothesis(): - * 1. add a case for the name of the new hypothesis and - * 2. initialize _pyHypothesis fields: - * . myDim - hypothesis dimention; - * . myType - type name of the algorithm creating the hypothesis; - * . myCreationMethod - method name of the algorithm creating the hypothesis; - * . append to myArgMethods interface methods setting param values in the - * order they are used when myCreationMethod is called. It is supposed that - * each interface method sets only one parameter, if it is not so, you are + * HOWTO assure convertion of a new type of hypothesis + * In _pyHypothesis::NewHypothesis(): + * 1. add a case for the name of the new hypothesis + * 2. use SetConvMethodAndType() to set + * . for algo: algorithm name and method of Mesh creating the algo + * . for hypo: name of the algorithm and method creating the hypothesis + * 3. append to myArgMethods interface methods setting param values in the + * order they are used when creation method is called. If arguments of + * the creation method can't be easily got from calls of hypothesis methods, you are * to derive a specific class from _pyHypothesis that would redefine Process(), * see _pyComplexParamHypo for example */ @@ -264,41 +260,43 @@ private: class _pyHypothesis: public _pyObject { protected: - bool myIsAlgo, myIsWrapped; //myIsLocal, myIsConverted; - //int myDim/*, myAdditionCmdNb*/; - _pyID myGeom, myMesh; - TCollection_AsciiString myCreationMethod, myType; - TColStd_SequenceOfAsciiString myArgs; - TColStd_SequenceOfAsciiString myArgMethods; - TColStd_SequenceOfInteger myNbArgsByMethod; + bool myIsAlgo, myIsWrapped; + _pyID myGeom, myMesh; + // a hypothesis can be used and created by different algos by different methods + std::map myType2CreationMethod; + //TCollection_AsciiString myCreationMethod, myType; + TColStd_SequenceOfAsciiString myArgs; // creation arguments + TColStd_SequenceOfAsciiString myArgMethods; // hypo methods setting myArgs + TColStd_SequenceOfInteger myNbArgsByMethod; // nb args set by each method std::list myArgCommands; std::list myUnknownCommands; public: _pyHypothesis(const Handle(_pyCommand)& theCreationCmd); - void SetConvMethodAndType(const char* creationMethod, const char* type=0) - { myCreationMethod = (char*)creationMethod; if ( type ) myType = (char*)type; } -// void SetDimMethodType(const int dim, const char* creationMethod, const char* type=0) -// { myDim = dim; myCreationMethod = (char*)creationMethod; if ( type ) myType = (char*)type; } + void SetConvMethodAndType(const char* creationMethod, const char* type) + { myType2CreationMethod[ (char*)type ] = (char*)creationMethod; } void AddArgMethod(const char* method, const int nbArgs = 1) { myArgMethods.Append( (char*)method ); myNbArgsByMethod.Append( nbArgs ); } const TColStd_SequenceOfAsciiString& GetArgs() const { return myArgs; } - const TCollection_AsciiString& GetCreationMethod() const { return myCreationMethod; } const std::list& GetArgCommands() const { return myArgCommands; } void ClearAllCommands(); virtual bool IsAlgo() const { return myIsAlgo; } + bool IsValid() const { return !myType2CreationMethod.empty(); } bool IsWrapped() const { return myIsWrapped; } - //bool & IsConverted() { return myIsConverted; } - //int GetDim() const { return myDim; } const _pyID & GetGeom() const { return myGeom; } void SetMesh( const _pyID& theMeshId) { if ( myMesh.IsEmpty() ) myMesh = theMeshId; } const _pyID & GetMesh() const { return myMesh; } - const TCollection_AsciiString GetType() { return myType; } + const TCollection_AsciiString& GetAlgoType() const + { return myType2CreationMethod.begin()->first; } + const TCollection_AsciiString& GetAlgoCreationMethod() const + { return myType2CreationMethod.begin()->second; } + bool CanBeCreatedBy(const TCollection_AsciiString& algoType ) const + { return myType2CreationMethod.find( algoType ) != myType2CreationMethod.end(); } + const TCollection_AsciiString& GetCreationMethod(const TCollection_AsciiString& algoType) const + { return myType2CreationMethod.find( algoType )->second; } bool IsWrappable(const _pyID& theMesh) { return !myIsWrapped && myMesh == theMesh; } virtual bool Addition2Creation( const Handle(_pyCommand)& theAdditionCmd, const _pyID& theMesh); static Handle(_pyHypothesis) NewHypothesis( const Handle(_pyCommand)& theCreationCmd); - // bool HasMesh() const { return !myMesh.IsEmpty(); } - // void SetGeom( const _pyID& theGeomID ) { myGeom = theGeomID; } void Process( const Handle(_pyCommand)& theCommand); void Flush(); diff --git a/src/SMESH_I/SMESH_Filter_i.cxx b/src/SMESH_I/SMESH_Filter_i.cxx index 85cec50a5..51bc29f22 100644 --- a/src/SMESH_I/SMESH_Filter_i.cxx +++ b/src/SMESH_I/SMESH_Filter_i.cxx @@ -396,48 +396,49 @@ static TopoDS_Shape getShapeByName( const char* theName ) return TopoDS_Shape(); } -static TopoDS_Shape getShapeByID( const char* theID ) +static TopoDS_Shape getShapeByID (const char* theID) { - if ( theID != 0 && theID!="" ) - { + if (theID != 0 && theID != "") { SMESH_Gen_i* aSMESHGen = SMESH_Gen_i::GetSMESHGen(); SALOMEDS::Study_ptr aStudy = aSMESHGen->GetCurrentStudy(); - if ( aStudy != 0 ) - { - CORBA::Object_var obj = aStudy->ConvertIORToObject(theID); - GEOM::GEOM_Object_var aGeomObj = GEOM::GEOM_Object::_narrow( obj ); + if (aStudy != 0) { + SALOMEDS::SObject_var aSObj = aStudy->FindObjectID(theID); + SALOMEDS::GenericAttribute_var anAttr; + if (!aSObj->_is_nil() && aSObj->FindAttribute(anAttr, "AttributeIOR")) { + SALOMEDS::AttributeIOR_var anIOR = SALOMEDS::AttributeIOR::_narrow(anAttr); + CORBA::String_var aVal = anIOR->Value(); + CORBA::Object_var obj = aStudy->ConvertIORToObject(aVal); + GEOM::GEOM_Object_var aGeomObj = GEOM::GEOM_Object::_narrow(obj); - if ( !aGeomObj->_is_nil() ) - { - GEOM::GEOM_Gen_ptr aGEOMGen = SMESH_Gen_i::GetGeomEngine(); + if (!aGeomObj->_is_nil()) { + GEOM::GEOM_Gen_ptr aGEOMGen = SMESH_Gen_i::GetGeomEngine(); TopoDS_Shape aLocShape = aSMESHGen->GetShapeReader()->GetShape( aGEOMGen, aGeomObj ); return aLocShape; } + } } } return TopoDS_Shape(); } -static char* getShapeNameByID ( const char* theID ) +static char* getShapeNameByID (const char* theID) { char* aName = ""; - if ( theID != 0 && theID!="" ) - { - SMESH_Gen_i* aSMESHGen = SMESH_Gen_i::GetSMESHGen(); - SALOMEDS::Study_ptr aStudy = aSMESHGen->GetCurrentStudy(); - if ( aStudy != 0 ) - { - SALOMEDS::SObject_var aSObj = aStudy->FindObjectIOR( theID ); - SALOMEDS::GenericAttribute_var anAttr; - if ( !aSObj->_is_nil() && aSObj->FindAttribute( anAttr, "AttributeName") ) - { - SALOMEDS::AttributeName_var aNameAttr = SALOMEDS::AttributeName::_narrow( anAttr ); - aName = aNameAttr->Value(); - } - } + if (theID != 0 && theID != "") { + SMESH_Gen_i* aSMESHGen = SMESH_Gen_i::GetSMESHGen(); + SALOMEDS::Study_ptr aStudy = aSMESHGen->GetCurrentStudy(); + if (aStudy != 0) { + //SALOMEDS::SObject_var aSObj = aStudy->FindObjectIOR( theID ); + SALOMEDS::SObject_var aSObj = aStudy->FindObjectID(theID); + SALOMEDS::GenericAttribute_var anAttr; + if (!aSObj->_is_nil() && aSObj->FindAttribute(anAttr, "AttributeName")) { + SALOMEDS::AttributeName_var aNameAttr = SALOMEDS::AttributeName::_narrow(anAttr); + aName = aNameAttr->Value(); + } } - + } + return aName; } @@ -2057,9 +2058,10 @@ CORBA::Boolean Filter_i::SetCriteria( const SMESH::Filter::Criteria& theCriteria ElementType aTypeOfElem = theCriteria[ i ].TypeOfElement; long aPrecision = theCriteria[ i ].Precision; - TPythonDump()<<"aCriterion = SMESH.Filter.Criterion("<< - aCriterion<<","<FindOrLoad_Component("FactoryServer","GEOM") ); + //CCRT return aGeomEngine._retn(); + if(CORBA::is_nil(myGeomGen)) { Engines::Component_ptr temp=GetLCC()->FindOrLoad_Component("FactoryServer","GEOM"); - myGeomGen = GEOM::GEOM_Gen::_narrow(temp); + myGeomGen=GEOM::GEOM_Gen::_narrow(temp); } return myGeomGen; } @@ -1233,13 +1235,14 @@ CORBA::Boolean SMESH_Gen_i::Compute( SMESH::SMESH_Mesh_ptr theMesh, // Update Python script TPythonDump() << "isDone = " << this << ".Compute( " << theMesh << ", " << theShapeObject << ")"; - TPythonDump() << "if not isDone: print 'Mesh', " << theMesh << ", ': computation failed'"; try { // get mesh servant SMESH_Mesh_i* meshServant = dynamic_cast( GetServant( theMesh ).in() ); ASSERT( meshServant ); if ( meshServant ) { + // NPAL16168: "geometrical group edition from a submesh don't modifiy mesh computation" + meshServant->CheckGeomGroupModif(); // get local TopoDS_Shape TopoDS_Shape myLocShape = GeomObjectToShape( theShapeObject ); // call implementation compute @@ -1247,9 +1250,8 @@ CORBA::Boolean SMESH_Gen_i::Compute( SMESH::SMESH_Mesh_ptr theMesh, return myGen.Compute( myLocMesh, myLocShape); } } - catch ( std::bad_alloc& exc ) { - THROW_SALOME_CORBA_EXCEPTION( "Memory allocation problem", - SALOME::INTERNAL_ERROR ); + catch ( std::bad_alloc ) { + INFOS( "Compute(): lack of memory" ); } catch ( SALOME_Exception& S_ex ) { INFOS( "Compute(): catch exception "<< S_ex.what() ); @@ -2670,6 +2672,7 @@ bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent, } // close hypotheses root HDF group aTopGroup->CloseOnDisk(); + aTopGroup = 0; } // --> then we should read&create algorithms @@ -2769,6 +2772,7 @@ bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent, } // close algorithms root HDF group aTopGroup->CloseOnDisk(); + aTopGroup = 0; } // --> the rest groups should be meshes @@ -3410,7 +3414,8 @@ bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent, } } // close mesh group - aTopGroup->CloseOnDisk(); + if(aTopGroup) + aTopGroup->CloseOnDisk(); } // close HDF file aFile->CloseOnDisk(); diff --git a/src/SMESH_I/SMESH_Gen_i_1.cxx b/src/SMESH_I/SMESH_Gen_i_1.cxx index e76000901..d179f62d1 100644 --- a/src/SMESH_I/SMESH_Gen_i_1.cxx +++ b/src/SMESH_I/SMESH_Gen_i_1.cxx @@ -32,6 +32,7 @@ #include "SMESH_Hypothesis_i.hxx" #include "SMESH_Algo_i.hxx" #include "SMESH_Group_i.hxx" +#include "SMESH_subMesh_i.hxx" #include "SMESH.hxx" diff --git a/src/SMESH_I/SMESH_Mesh_i.cxx b/src/SMESH_I/SMESH_Mesh_i.cxx index 76e5a9821..d10e90141 100644 --- a/src/SMESH_I/SMESH_Mesh_i.cxx +++ b/src/SMESH_I/SMESH_Mesh_i.cxx @@ -52,6 +52,7 @@ #include "SMESH_MeshEditor.hxx" // OCCT Includes +#include #include #include #include @@ -59,7 +60,8 @@ #include #include #include -#include "TCollection_AsciiString.hxx" +#include +#include // STL Includes #include @@ -956,6 +958,139 @@ SMESH::SMESH_Group_ptr SMESH_Mesh_i::CutGroups( SMESH::SMESH_GroupBase_ptr theGr return aResGrp._retn(); } +//================================================================================ +/*! + * \brief Return group items of a group present in a study + */ +//================================================================================ + +static GEOM::GEOM_Object_ptr getGroupItemsFromStudy(CORBA::Object_ptr theMesh, + SMESH_Gen_i* theGen, + list & theItems) +{ + GEOM::GEOM_Object_var groupObj; + SALOMEDS::Study_var study = theGen->GetCurrentStudy(); + GEOM::GEOM_Gen_var geomGen = theGen->GetGeomEngine(); + if ( study->_is_nil() || geomGen->_is_nil() ) + return groupObj._retn(); + + GEOM::GEOM_IGroupOperations_var groupOp = + geomGen->GetIGroupOperations( theGen->GetCurrentStudyID() ); + GEOM::GEOM_IShapesOperations_var shapeOp = + geomGen->GetIShapesOperations( theGen->GetCurrentStudyID() ); + + SALOMEDS::SObject_var meshOS = theGen->ObjectToSObject(study, theMesh); + if ( meshOS->_is_nil() || groupOp->_is_nil() || shapeOp->_is_nil() ) + return groupObj._retn(); + SALOMEDS::SObject_var fatherSO = meshOS->GetFather(); + if ( fatherSO->_is_nil() || fatherSO->Tag() != theGen->GetSubMeshOnCompoundTag() ) + return groupObj._retn(); // keep only submeshes on groups + + SALOMEDS::ChildIterator_var anIter = study->NewChildIterator(meshOS); + if ( anIter->_is_nil() ) return groupObj._retn(); + for ( ; anIter->More(); anIter->Next()) + { + SALOMEDS::SObject_var aSObject = anIter->Value(); + SALOMEDS::SObject_var aRefSO; + if ( !aSObject->_is_nil() && aSObject->ReferencedObject(aRefSO) ) + { + groupObj = GEOM::GEOM_Object::_narrow(aRefSO->GetObject()); + if ( groupObj->_is_nil() ) break; + GEOM::ListOfLong_var ids = groupOp->GetObjects( groupObj ); + GEOM::GEOM_Object_var mainShape = groupObj->GetMainShape(); + for ( int i = 0; i < ids->length(); ++i ) { + GEOM::GEOM_Object_var subShape = shapeOp->GetSubShape( mainShape, ids[i] ); + TopoDS_Shape S = theGen->GeomObjectToShape( subShape ); + if ( !S.IsNull() ) + theItems.push_back( S ); + } + break; + } + } + return groupObj._retn(); +} + +//============================================================================= +/*! + * \brief Update hypotheses assigned to geom groups if the latter change + * + * NPAL16168: "geometrical group edition from a submesh don't modifiy mesh computation" + */ +//============================================================================= + +void SMESH_Mesh_i::CheckGeomGroupModif() +{ + if ( !_impl->HasShapeToMesh() ) return; + + SALOMEDS::Study_var study = _gen_i->GetCurrentStudy(); + if ( study->_is_nil() ) return; + + // check if items of groups changed + map::iterator i_sm = _mapSubMesh.begin(); + for ( ; i_sm != _mapSubMesh.end(); ++i_sm ) + { + const TopoDS_Shape & oldGroupShape = i_sm->second->GetSubShape(); + SMESHDS_SubMesh * oldDS = i_sm->second->GetSubMeshDS(); + if ( !oldDS /*|| !oldDS->IsComplexSubmesh()*/ ) + continue; + int oldID = i_sm->first; + map::iterator i_smIor = _mapSubMeshIor.find( oldID ); + if ( i_smIor == _mapSubMeshIor.end() ) + continue; + list< TopoDS_Shape> newItems; + GEOM::GEOM_Object_var groupObj = getGroupItemsFromStudy ( i_smIor->second, _gen_i, newItems ); + if ( groupObj->_is_nil() ) + continue; + + int nbOldItems = oldDS->IsComplexSubmesh() ? oldDS->NbSubMeshes() : 1; + int nbNewItems = newItems.size(); + bool groupChanged = ( nbOldItems != nbNewItems); + if ( !groupChanged ) { + if ( !oldDS->IsComplexSubmesh() ) { // old group has one item + groupChanged = ( oldGroupShape != newItems.front() ); + } + else { + list::iterator item = newItems.begin(); + for ( ; item != newItems.end() && !groupChanged; ++item ) + { + SMESHDS_SubMesh * itemDS = _impl->GetMeshDS()->MeshElements( *item ); + groupChanged = ( !itemDS || !oldDS->ContainsSubMesh( itemDS )); + } + } + } + // update hypotheses and submeshes if necessary + if ( groupChanged ) + { + // get a new group shape + GEOM_Client* geomClient = _gen_i->GetShapeReader(); + if ( !geomClient ) continue; + TCollection_AsciiString groupIOR = _gen_i->GetGeomEngine()->GetStringFromIOR( groupObj ); + geomClient->RemoveShapeFromBuffer( groupIOR ); + TopoDS_Shape newGroupShape = _gen_i->GeomObjectToShape( groupObj ); + // update hypotheses + list hyps = _impl->GetHypothesisList(oldGroupShape); + list ::iterator hypIt; + for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt ) + { + _impl->RemoveHypothesis( oldGroupShape, (*hypIt)->GetID()); + _impl->AddHypothesis ( newGroupShape, (*hypIt)->GetID()); + } + // care of submeshes + SMESH_subMesh* newSubmesh = _impl->GetSubMesh( newGroupShape ); + int newID = newSubmesh->GetId(); + if ( newID != oldID ) { + _mapSubMesh [ newID ] = newSubmesh; + _mapSubMesh_i [ newID ] = _mapSubMesh_i [ oldID ]; + _mapSubMeshIor[ newID ] = _mapSubMeshIor[ oldID ]; + _mapSubMesh.erase (oldID); + _mapSubMesh_i.erase (oldID); + _mapSubMeshIor.erase(oldID); + _mapSubMesh_i [ newID ]->changeLocalId( newID ); + } + } + } +} + //============================================================================= /*! * diff --git a/src/SMESH_I/SMESH_Mesh_i.hxx b/src/SMESH_I/SMESH_Mesh_i.hxx index af50b569b..8ad479376 100644 --- a/src/SMESH_I/SMESH_Mesh_i.hxx +++ b/src/SMESH_I/SMESH_Mesh_i.hxx @@ -40,13 +40,14 @@ #include "SMESH_Hypothesis.hxx" #include "SMESH_Mesh.hxx" -#include "SMESH_subMesh_i.hxx" +//#include "SMESH_subMesh_i.hxx" #include "SMESH_subMesh.hxx" #include "SALOME_GenericObj_i.hh" class SMESH_Gen_i; class SMESH_GroupBase_i; +class SMESH_subMesh_i; #include @@ -312,6 +313,13 @@ public: const map& getGroups() { return _mapGroups; } // return an existing group object. + /*! + * \brief Update hypotheses assigned to geom groups if the latter change + * + * NPAL16168: "geometrical group edition from a submesh don't modifiy mesh computation" + */ + void CheckGeomGroupModif(); + virtual SMESH::long_array* GetIDs(); CORBA::LongLong GetMeshPtr(); diff --git a/src/SMESH_I/SMESH_Pattern_i.cxx b/src/SMESH_I/SMESH_Pattern_i.cxx index 13ed3ac89..4f730b387 100644 --- a/src/SMESH_I/SMESH_Pattern_i.cxx +++ b/src/SMESH_I/SMESH_Pattern_i.cxx @@ -40,6 +40,9 @@ #include #include +#include +#include + #include #include @@ -286,8 +289,24 @@ SMESH::point_array* if ( elem && elem->GetType() == SMDSAbs_Face ) fset.insert( static_cast( elem )); } - if (myPattern.Apply( fset, theNodeIndexOnKeyPoint1, theReverse ) && - myPattern.GetMappedPoints( xyzList )) + bool ok = false; + try { +#if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100 + OCC_CATCH_SIGNALS; +#endif + ok = myPattern.Apply( aMesh, fset, theNodeIndexOnKeyPoint1, theReverse ); + } + catch (Standard_Failure& exc) { + MESSAGE("OCCT Exception in SMESH_Pattern: " << exc.GetMessageString()); + } + catch ( std::exception& exc ) { + MESSAGE("STD Exception in SMESH_Pattern: << exc.what()"); + } + catch ( ... ) { + MESSAGE("Unknown Exception in SMESH_Pattern"); + } + + if ( ok && myPattern.GetMappedPoints( xyzList )) { points->length( xyzList.size() ); list::iterator xyzIt = xyzList.begin(); diff --git a/src/SMESH_I/SMESH_PythonDump.hxx b/src/SMESH_I/SMESH_PythonDump.hxx index 6e65a3d41..518e1be92 100644 --- a/src/SMESH_I/SMESH_PythonDump.hxx +++ b/src/SMESH_I/SMESH_PythonDump.hxx @@ -31,6 +31,37 @@ class SMESH_Gen_i; class SMESH_MeshEditor_i; class TCollection_AsciiString; +class Resource_DataMapOfAsciiStringAsciiString; + +// =========================================================================================== +/*! + * \brief Tool converting SMESH engine calls into commands defined in smesh.py + * + * Implementation is in SMESH_2smeshpy.cxx + */ +// =========================================================================================== + +class SMESH_2smeshpy +{ +public: + /*! + * \brief Convert a python script using commands of smesh.py + * \param theScript - Input script + * \param theEntry2AccessorMethod - The returning method names to access to + * objects wrapped with python class + * \retval TCollection_AsciiString - Convertion result + */ + static TCollection_AsciiString + ConvertScript(const TCollection_AsciiString& theScript, + Resource_DataMapOfAsciiStringAsciiString& theEntry2AccessorMethod); + + /*! + * \brief Return the name of the python file wrapping IDL API + * \retval TCollection_AsciiString - The file name + */ + static char* SmeshpyName() { return "smesh"; } + static char* GenName() { return "smesh.smesh"; } +}; namespace SMESH { @@ -39,6 +70,12 @@ namespace SMESH class Filter_i; class Functor_i; +// =========================================================================================== +/*! + * \brief Utility helping in storing SMESH engine calls as python commands + */ +// =========================================================================================== + class SMESH_I_EXPORT TPythonDump { std::ostringstream myStream; @@ -144,5 +181,4 @@ namespace SMESH }; } - #endif diff --git a/src/SMESH_I/SMESH_subMesh_i.cxx b/src/SMESH_I/SMESH_subMesh_i.cxx index 4df569cb6..da14ee1f7 100644 --- a/src/SMESH_I/SMESH_subMesh_i.cxx +++ b/src/SMESH_I/SMESH_subMesh_i.cxx @@ -458,8 +458,14 @@ GEOM::GEOM_Object_ptr SMESH_subMesh_i::GetSubShape() try { if ( _mesh_i->_mapSubMesh.find( _localId ) != _mesh_i->_mapSubMesh.end()) { TopoDS_Shape S = _mesh_i->_mapSubMesh[ _localId ]->GetSubShape(); - if ( !S.IsNull() ) + if ( !S.IsNull() ) { aShapeObj = _gen_i->ShapeToGeomObject( S ); + //mzn: N7PAL16232, N7PAL16233 + //In some cases it's possible that GEOM_Client contains the shape same to S, but + //with another orientation. + if (aShapeObj->_is_nil()) + aShapeObj = _gen_i->ShapeToGeomObject( S.Reversed() ); + } } } catch(SALOME_Exception & S_ex) { diff --git a/src/SMESH_I/SMESH_subMesh_i.hxx b/src/SMESH_I/SMESH_subMesh_i.hxx index 808b07cb6..154ffd7a2 100644 --- a/src/SMESH_I/SMESH_subMesh_i.hxx +++ b/src/SMESH_I/SMESH_subMesh_i.hxx @@ -38,6 +38,7 @@ #include CORBA_CLIENT_HEADER(MED) #include "SALOME_GenericObj_i.hh" +#include "SMESH_Mesh_i.hxx" class SMESH_Gen_i; class SMESH_Mesh_i; @@ -91,8 +92,11 @@ public: SMESH_Mesh_i* _mesh_i; //NRI protected: + void changeLocalId(int localId) { _localId = localId; } SMESH_Gen_i* _gen_i; int _localId; + + friend void SMESH_Mesh_i::CheckGeomGroupModif(); }; #endif diff --git a/src/SMESH_SWIG/Makefile.am b/src/SMESH_SWIG/Makefile.am index 9092d0811..09ab5553d 100644 --- a/src/SMESH_SWIG/Makefile.am +++ b/src/SMESH_SWIG/Makefile.am @@ -27,87 +27,9 @@ include $(top_srcdir)/adm_local/unix/make_common_starter.am -# =============================================================== -# Swig targets -# =============================================================== -# (cf. http://www.geocities.com/foetsch/python/swig_linux.htm) -# -# Step 1: build the wrapping source files with swig -# -# libSALOME_LifeCycleCORBA.i -- swig --> swig_wrap.cpp -# libSALOME_Swig.py -# -# Step 2: build the dynamic library from cpp built source files and -# dependant libraries. -# -# swig_wrap.cpp -- gcc --> swig_wrap.o |-- link --> _libSALOME_Swig.la -# + | -# dependant libs | -# -# The file libSALOME_Swigcmodule.py will be installed in -# /lib/python/site-package/salome. -# The library will be installed in the same place. -# - -# this option puts it to dist -#BUILT_SOURCES = swig_wrap.cpp - -SWIG_FLAGS = \ - @SWIG_FLAGS@ \ - -I$(srcdir) \ - -I$(srcdir)/../SMESHGUI - -SWIG_SOURCES = libSMESH_Swig.i - -# Libraries targets - -lib_LTLIBRARIES = libSMESH_Swigcmodule.la - -nodist_pkgpython_DATA = libSMESH_Swig.py -libSMESH_Swig.py: swig_wrap.cpp - -libSMESH_Swigcmodule_la_SOURCES = \ - $(BUILT_SOURCES) \ - $(SWIG_SOURCES) \ - ../SMESHGUI/SMESHGUI_Swig.cxx - -nodist_libSMESH_Swigcmodule_la_SOURCES = \ - swig_wrap.cpp - -libSMESH_Swigcmodule_la_CPPFLAGS = \ - $(QT_INCLUDES) \ - $(PYTHON_INCLUDES) \ - $(CAS_CPPFLAGS) \ - $(VTK_INCLUDES) \ - $(OGL_INCLUDES) \ - $(KERNEL_CXXFLAGS) \ - $(GUI_CXXFLAGS) \ - $(MED_CXXFLAGS) \ - $(GEOM_CXXFLAGS) \ - $(CORBA_CXXFLAGS) \ - $(CORBA_INCLUDES) \ - $(BOOST_CPPFLAGS) \ - -I$(srcdir)/../SMESHGUI \ - -I$(top_builddir)/idl \ - -I$(top_builddir)/salome_adm/unix - -libSMESH_Swigcmodule_la_LDFLAGS = \ - ../SMESHGUI/libSMESH.la \ - $(KERNEL_LDFLAGS) -lSalomeGenericObj -lSALOMELocalTrace \ - $(GUI_LDFLAGS) -lCAM -lsuit -lqtx -lSalomeApp -lstd -lEvent \ - $(PYTHON_LIBS) \ - $(QT_MT_LIBS) - - -swig_wrap.cpp : $(SWIG_SOURCES) - $(SWIG) $(SWIG_FLAGS) -o $@ $< - -CLEANFILES = \ - swig_wrap.cpp # Scripts to be installed. dist_salomescript_DATA= \ - libSMESH_Swig.py \ smesh.py \ smeshDC.py \ batchmode_smesh.py \ @@ -173,8 +95,3 @@ dist_salomescript_DATA= \ EXPORT_SHAREDPYSCRIPTS = \ SMESH_shared_modules.py - -install-exec-hook: $(libdir)/_libSMESH_Swig.so - -$(libdir)/_libSMESH_Swig.so: - ( cd $(libdir); ln -sf libSMESH_Swigcmodule.so _libSMESH_Swig.so; ) diff --git a/src/SMESH_SWIG/libSMESH_Swig.i b/src/SMESH_SWIG/libSMESH_Swig.i deleted file mode 100644 index 247c0fc39..000000000 --- a/src/SMESH_SWIG/libSMESH_Swig.i +++ /dev/null @@ -1,30 +0,0 @@ -// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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 : libGeometry_Swig.i -// Author : Nicolas REJNERI, Paul RASCLE -// Module : SMESH -// $Header$ - -%module libSMESH_Swig - -%include "SMESHGUI_Swig.i" - diff --git a/src/SMESH_SWIG/smeshDC.py b/src/SMESH_SWIG/smeshDC.py index 5b6ee694b..d9881a6a7 100644 --- a/src/SMESH_SWIG/smeshDC.py +++ b/src/SMESH_SWIG/smeshDC.py @@ -29,7 +29,7 @@ import salome import geompyDC -import SMESH +import SMESH # necessary for back compatibility from SMESH import * import StdMeshers @@ -49,10 +49,14 @@ REGULAR = 1 PYTHON = 2 COMPOSITE = 3 -MEFISTO = 3 -NETGEN = 4 -GHS3D = 5 -FULL_NETGEN = 6 +MEFISTO = 3 +NETGEN = 4 +GHS3D = 5 +FULL_NETGEN = 6 +NETGEN_2D = 7 +NETGEN_1D2D = NETGEN +NETGEN_1D2D3D = FULL_NETGEN +NETGEN_FULL = FULL_NETGEN # MirrorType enumeration POINT = SMESH_MeshEditor.POINT @@ -413,6 +417,13 @@ class Mesh_Algorithm: self.geom = 0 self.subm = 0 self.algo = 0 + hypos = {} + + def FindHypothesis(self,hypname, args): + key = "%s %s %s" % (self.__class__.__name__, hypname, args) + if Mesh_Algorithm.hypos.has_key( key ): + return Mesh_Algorithm.hypos[ key ] + return None ## If the algorithm is global, return 0; \n # else return the submesh associated to this algorithm. @@ -444,41 +455,57 @@ class Mesh_Algorithm: ## Private method. def Create(self, mesh, geom, hypo, so="libStdMeshersEngine.so"): + if geom is None: + raise RuntimeError, "Attemp to create " + hypo + " algoritm on None shape" + algo = smesh.CreateHypothesis(hypo, so) + self.Assign(algo, mesh, geom) + return self.algo + + ## Private method + def Assign(self, algo, mesh, geom): if geom is None: raise RuntimeError, "Attemp to create " + hypo + " algoritm on None shape" self.mesh = mesh piece = mesh.geom - if geom==0: + if not geom: self.geom = piece - name = GetName(piece) else: self.geom = geom name = GetName(geom) if name==NO_NAME: name = mesh.geompyD.SubShapeName(geom, piece) mesh.geompyD.addToStudyInFather(piece, geom, name) - self.subm = mesh.mesh.GetSubMesh(geom, hypo) + self.subm = mesh.mesh.GetSubMesh(geom, algo.GetName()) - self.algo = mesh.smeshpyD.CreateHypothesis(hypo, so) - SetName(self.algo, name + "/" + hypo) + self.algo = algo status = mesh.mesh.AddHypothesis(self.geom, self.algo) - TreatHypoStatus( status, hypo, name, 1 ) - + TreatHypoStatus( status, algo.GetName(), GetName(algo), True ) + ## Private method - def Hypothesis(self, hyp, args=[], so="libStdMeshersEngine.so"): - hypo = self.mesh.smeshpyD.CreateHypothesis(hyp, so) - a = "" - s = "=" - i = 0 - n = len(args) - while i-th node of each volume, the (0,0,1) # key-point will be mapped into -th node of each volume. # The (0,0,0) key-point of used pattern corresponds to not split corner. - # @param @return TRUE in case of success, FALSE otherwise. + # @return TRUE in case of success, FALSE otherwise. def SplitHexaToTetras (self, theObject, theNode000, theNode001): # Pattern: 5.---------.6 # /|#* /| @@ -2142,7 +2384,7 @@ class Mesh: # will be mapped into -th node of each volume, the (0,0,1) # key-point will be mapped into -th node of each volume. # The edge (0,0,0)-(0,0,1) of used pattern connects two not split corners. - # @param @return TRUE in case of success, FALSE otherwise. + # @return TRUE in case of success, FALSE otherwise. def SplitHexaToPrisms (self, theObject, theNode000, theNode001): # Pattern: 5.---------.6 # /|# /| @@ -2219,7 +2461,7 @@ class Mesh: # @param MaxNbOfIterations maximum number of iterations # @param MaxAspectRatio varies in range [1.0, inf] # @param Method is Laplacian(LAPLACIAN_SMOOTH) or Centroidal(CENTROIDAL_SMOOTH) - def SmoothParametric(self,IDsOfElements, IDsOfFixedNodes, + def SmoothParametric(self, IDsOfElements, IDsOfFixedNodes, MaxNbOfIterations, MaxAspectRatio, Method): if IDsOfElements == []: IDsOfElements = self.GetElementsId() diff --git a/src/SMESH_SWIG_WITHIHM/Makefile.am b/src/SMESH_SWIG_WITHIHM/Makefile.am new file mode 100644 index 000000000..7988a23ea --- /dev/null +++ b/src/SMESH_SWIG_WITHIHM/Makefile.am @@ -0,0 +1,115 @@ +# Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +# +# 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 : Makefile.in +# Author : Nicolas REJNERI, Paul RASCLE +# Modified by : Alexander BORODIN (OCN) - autotools usage +# Module : SMESH +# $Header$ + +include $(top_srcdir)/adm_local/unix/make_common_starter.am + +# =============================================================== +# Swig targets +# =============================================================== +# (cf. http://www.geocities.com/foetsch/python/swig_linux.htm) +# +# Step 1: build the wrapping source files with swig +# +# libSALOME_LifeCycleCORBA.i -- swig --> swig_wrap.cpp +# libSALOME_Swig.py +# +# Step 2: build the dynamic library from cpp built source files and +# dependant libraries. +# +# swig_wrap.cpp -- gcc --> swig_wrap.o |-- link --> _libSALOME_Swig.la +# + | +# dependant libs | +# +# The file libSALOME_Swigcmodule.py will be installed in +# /lib/python/site-package/salome. +# The library will be installed in the same place. +# + +# this option puts it to dist +#BUILT_SOURCES = swig_wrap.cpp + +SWIG_FLAGS = \ + @SWIG_FLAGS@ \ + -I$(srcdir) \ + -I$(srcdir)/../SMESHGUI + +SWIG_SOURCES = libSMESH_Swig.i + +# Libraries targets + +lib_LTLIBRARIES = libSMESH_Swigcmodule.la + +nodist_pkgpython_DATA = libSMESH_Swig.py +libSMESH_Swig.py: swig_wrap.cpp + +libSMESH_Swigcmodule_la_SOURCES = \ + $(BUILT_SOURCES) \ + $(SWIG_SOURCES) \ + ../SMESHGUI/SMESHGUI_Swig.cxx + +nodist_libSMESH_Swigcmodule_la_SOURCES = \ + swig_wrap.cpp + +libSMESH_Swigcmodule_la_CPPFLAGS = \ + $(QT_INCLUDES) \ + $(PYTHON_INCLUDES) \ + $(CAS_CPPFLAGS) \ + $(VTK_INCLUDES) \ + $(OGL_INCLUDES) \ + $(KERNEL_CXXFLAGS) \ + $(GUI_CXXFLAGS) \ + $(MED_CXXFLAGS) \ + $(GEOM_CXXFLAGS) \ + $(CORBA_CXXFLAGS) \ + $(CORBA_INCLUDES) \ + $(BOOST_CPPFLAGS) \ + -I$(srcdir)/../SMESHGUI \ + -I$(top_builddir)/idl \ + -I$(top_builddir)/salome_adm/unix + +libSMESH_Swigcmodule_la_LDFLAGS = \ + ../SMESHGUI/libSMESH.la \ + $(KERNEL_LDFLAGS) -lSalomeGenericObj -lSALOMELocalTrace \ + $(GUI_LDFLAGS) -lCAM -lsuit -lqtx -lSalomeApp -lstd -lEvent \ + $(PYTHON_LIBS) \ + $(QT_MT_LIBS) + + +swig_wrap.cpp : $(SWIG_SOURCES) + $(SWIG) $(SWIG_FLAGS) -o $@ $< + +CLEANFILES = \ + swig_wrap.cpp + +# Scripts to be installed. +dist_salomescript_DATA= \ + libSMESH_Swig.py + +install-exec-hook: $(libdir)/_libSMESH_Swig.so + +$(libdir)/_libSMESH_Swig.so: + ( cd $(libdir); ln -sf libSMESH_Swigcmodule.so _libSMESH_Swig.so; ) diff --git a/src/SMESH_SWIG_WITHIHM/libSMESH_Swig.i b/src/SMESH_SWIG_WITHIHM/libSMESH_Swig.i new file mode 100644 index 000000000..247c0fc39 --- /dev/null +++ b/src/SMESH_SWIG_WITHIHM/libSMESH_Swig.i @@ -0,0 +1,30 @@ +// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// 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 : libGeometry_Swig.i +// Author : Nicolas REJNERI, Paul RASCLE +// Module : SMESH +// $Header$ + +%module libSMESH_Swig + +%include "SMESHGUI_Swig.i" + diff --git a/src/StdMeshers/StdMeshers_CompositeSegment_1D.cxx b/src/StdMeshers/StdMeshers_CompositeSegment_1D.cxx index 1820f6fe3..c60cbee61 100644 --- a/src/StdMeshers/StdMeshers_CompositeSegment_1D.cxx +++ b/src/StdMeshers/StdMeshers_CompositeSegment_1D.cxx @@ -91,8 +91,7 @@ namespace { eNext = TopoDS::Edge( ancestor ); } if ( edgeCounter.Extent() < 3 && !eNext.IsNull() ) { - GeomAbs_Shape cont = SMESH_Algo::Continuity( edge, eNext ); - if (cont >= GeomAbs_G1) { + if ( SMESH_Algo::IsContinuous( edge, eNext )) { // care of orientation bool reverse; if ( forward ) diff --git a/src/StdMeshers/StdMeshers_FaceSide.cxx b/src/StdMeshers/StdMeshers_FaceSide.cxx index 85057fb5c..3063577c0 100644 --- a/src/StdMeshers/StdMeshers_FaceSide.cxx +++ b/src/StdMeshers/StdMeshers_FaceSide.cxx @@ -35,6 +35,8 @@ #include "SMESH_Algo.hxx" #include "SMESH_Mesh.hxx" #include "SMESH_MeshEditor.hxx" +#include "SMESH_ComputeError.hxx" +#include "SMESH_Block.hxx" #include #include @@ -464,3 +466,50 @@ gp_Pnt2d StdMeshers_FaceSide::Value2d(double U) const } return gp_Pnt2d( 1e+100, 1e+100 ); } + +//================================================================================ +/*! + * \brief Return wires of a face as StdMeshers_FaceSide's + */ +//================================================================================ + +TSideVector StdMeshers_FaceSide::GetFaceWires(const TopoDS_Face& theFace, + SMESH_Mesh & theMesh, + const bool theIgnoreMediumNodes, + TError & theError) +{ + TopoDS_Vertex V1; + list< TopoDS_Edge > edges; + list< int > nbEdgesInWires; + int nbWires = SMESH_Block::GetOrderedEdges (theFace, V1, edges, nbEdgesInWires); + + // split list of all edges into separate wires + TSideVector wires( nbWires ); + list< int >::iterator nbE = nbEdgesInWires.begin(); + list< TopoDS_Edge >::iterator from, to; + from = to = edges.begin(); + for ( int iW = 0; iW < nbWires; ++iW ) + { + std::advance( to, *nbE++ ); + list< TopoDS_Edge > wireEdges( from, to ); + // assure that there is a node on the first vertex + // as StdMeshers_FaceSide::GetUVPtStruct() requires + while ( !SMESH_Algo::VertexNode( TopExp::FirstVertex( wireEdges.front(), true), + theMesh.GetMeshDS())) + { + wireEdges.splice(wireEdges.end(), wireEdges, + wireEdges.begin(), ++wireEdges.begin()); + if ( from->IsSame( wireEdges.front() )) { + theError = TError + ( new SMESH_ComputeError(COMPERR_BAD_INPUT_MESH,"No nodes on vertices")); + return TSideVector(0); + } + } + StdMeshers_FaceSide* wire = new StdMeshers_FaceSide( theFace, wireEdges, &theMesh, + true, theIgnoreMediumNodes); + wires[ iW ] = StdMeshers_FaceSidePtr( wire ); + from = to; + } + return wires; +} + diff --git a/src/StdMeshers/StdMeshers_FaceSide.hxx b/src/StdMeshers/StdMeshers_FaceSide.hxx index 1463d2d1f..43c92bf2b 100644 --- a/src/StdMeshers/StdMeshers_FaceSide.hxx +++ b/src/StdMeshers/StdMeshers_FaceSide.hxx @@ -45,6 +45,7 @@ class Adaptor2d_Curve2d; class Adaptor3d_Curve; class BRepAdaptor_CompCurve; class TopoDS_Face; +class SMESH_ComputeError; typedef struct uvPtStruct { @@ -61,6 +62,8 @@ typedef struct uvPtStruct class StdMeshers_FaceSide; typedef boost::shared_ptr< StdMeshers_FaceSide > StdMeshers_FaceSidePtr; typedef boost::shared_ptr< uvPtStruct > UVPtStructPtr; +typedef std::vector< StdMeshers_FaceSidePtr > TSideVector; +typedef boost::shared_ptr< SMESH_ComputeError > TError; //================================================================================ /*! @@ -88,6 +91,15 @@ public: SMESH_Mesh* theMesh, const bool theIsForward, const bool theIgnoreMediumNodes); + + /*! + * \brief Return wires of a face as StdMeshers_FaceSide's + */ + static TSideVector GetFaceWires(const TopoDS_Face& theFace, + SMESH_Mesh & theMesh, + const bool theIgnoreMediumNodes, + TError & theError); + /*! * \brief Change orientation of side geometry */ @@ -115,15 +127,15 @@ public: * * Missing nodes are allowed only on internal vertices */ - const vector& GetUVPtStruct(bool isXConst, double constValue) const; + const vector& GetUVPtStruct(bool isXConst =0, double constValue =0) const; /*! * \brief Simulates detailed data on nodes * \param isXConst - true if normalized parameter X is constant * \param constValue - constant parameter value */ const vector& SimulateUVPtStruct(int nbSeg, - bool isXConst, - double constValue) const; + bool isXConst = 0, + double constValue = 0) const; /*! * \brief Return edge and parameter on edge by normalized parameter */ diff --git a/src/StdMeshers/StdMeshers_Hexa_3D.cxx b/src/StdMeshers/StdMeshers_Hexa_3D.cxx index 80cd6caeb..d1567ae08 100644 --- a/src/StdMeshers/StdMeshers_Hexa_3D.cxx +++ b/src/StdMeshers/StdMeshers_Hexa_3D.cxx @@ -118,12 +118,15 @@ bool StdMeshers_Hexa_3D::CheckHypothesis SMESH_Hypothesis::Hypothesis_Status& aStatus) { // check nb of faces in the shape +/* PAL16229 aStatus = SMESH_Hypothesis::HYP_BAD_GEOMETRY; int nbFaces = 0; for (TopExp_Explorer exp(aShape, TopAbs_FACE); exp.More(); exp.Next()) if ( ++nbFaces > 6 ) - return false; - + break; + if ( nbFaces != 6 ) + return false; +*/ aStatus = SMESH_Hypothesis::HYP_OK; return true; } @@ -174,9 +177,10 @@ static bool findIJ (const SMDS_MeshNode* node, const FaceQuadStruct * quad, int& //============================================================================= bool StdMeshers_Hexa_3D::Compute(SMESH_Mesh & aMesh, - const TopoDS_Shape & aShape) throw(SALOME_Exception) + const TopoDS_Shape & aShape)// throw(SALOME_Exception) { - Unexpect aCatch(SalomeException); + // PAL14921. Enable catching std::bad_alloc and Standard_OutOfMemory outside + //Unexpect aCatch(SalomeException); MESSAGE("StdMeshers_Hexa_3D::Compute"); SMESHDS_Mesh * meshDS = aMesh.GetMeshDS(); @@ -190,7 +194,7 @@ bool StdMeshers_Hexa_3D::Compute(SMESH_Mesh & aMesh, meshFaces.push_back(aSubMesh); } if (meshFaces.size() != 6) - return error(COMPERR_BAD_SHAPE, TComm(meshFaces.size())<<" instead of 6 faces in block"); + return error(COMPERR_BAD_SHAPE, TComm(meshFaces.size())<<" instead of 6 faces in a block"); // 0.2 - is each face meshed with Quadrangle_2D? (so, with a wire of 4 edges) @@ -251,6 +255,9 @@ bool StdMeshers_Hexa_3D::Compute(SMESH_Mesh & aMesh, ASSERT(quadAlgo); try { aQuads[i] = quadAlgo->CheckAnd2Dcompute(aMesh, aFace, _quadraticMesh); + if(!aQuads[i]) { + return error( quadAlgo->GetComputeError()); + } } catch(SALOME_Exception & S_ex) { return ClearAndReturn( aQuads, error(COMPERR_SLM_EXCEPTION,TComm(S_ex.what()) << diff --git a/src/StdMeshers/StdMeshers_Hexa_3D.hxx b/src/StdMeshers/StdMeshers_Hexa_3D.hxx index 09aa81303..1f1c4042d 100644 --- a/src/StdMeshers/StdMeshers_Hexa_3D.hxx +++ b/src/StdMeshers/StdMeshers_Hexa_3D.hxx @@ -76,7 +76,7 @@ public: virtual bool Compute(SMESH_Mesh& aMesh, const TopoDS_Shape& aShape) - throw (SALOME_Exception); + /*throw (SALOME_Exception)*/; static TopoDS_Vertex OppositeVertex(const TopoDS_Vertex& aVertex, const TopTools_IndexedMapOfShape& aQuads0Vertices, diff --git a/src/StdMeshers/StdMeshers_MEFISTO_2D.cxx b/src/StdMeshers/StdMeshers_MEFISTO_2D.cxx index cb4e61fc1..ebf208060 100644 --- a/src/StdMeshers/StdMeshers_MEFISTO_2D.cxx +++ b/src/StdMeshers/StdMeshers_MEFISTO_2D.cxx @@ -187,42 +187,29 @@ bool StdMeshers_MEFISTO_2D::Compute(SMESH_Mesh & aMesh, const TopoDS_Shape & aSh const bool ignoreMediumNodes = _quadraticMesh; // get all edges of a face - TopoDS_Vertex V1; - list< TopoDS_Edge > edges; - list< int > nbEdgesInWires; - int nbWires = SMESH_Block::GetOrderedEdges (F, V1, edges, nbEdgesInWires); - - if (_hypLengthFromEdges) _edgeLength = 0; - - // split list of all edges into separate wires - TWireVector wires ( nbWires ); - list< int >::iterator nbE = nbEdgesInWires.begin(); - list< TopoDS_Edge >::iterator from, to; - from = to = edges.begin(); - for ( int iW = 0; iW < nbWires; ++iW ) + TError problem; + TWireVector wires = StdMeshers_FaceSide::GetFaceWires( F, aMesh, ignoreMediumNodes, problem ); + int nbWires = wires.size(); + if ( problem && !problem->IsOK() ) return error( problem ); + if ( nbWires == 0 ) return error( "Problem in StdMeshers_FaceSide::GetFaceWires()"); + if ( wires[0]->NbSegments() < 3 ) // ex: a circle with 2 segments + return error(COMPERR_BAD_INPUT_MESH, + SMESH_Comment("Too few segments: ")<NbSegments()); + + // compute average edge length + if (_hypLengthFromEdges) { - std::advance( to, *nbE++ ); - list< TopoDS_Edge > wireEdges( from, to ); - // assure that there is a node on the first vertex - // as StdMeshers_FaceSide::GetUVPtStruct() requires - while ( !VertexNode( TopExp::FirstVertex( wireEdges.front(), true), - aMesh.GetMeshDS())) + _edgeLength = 0; + int nbSegments = 0; + for ( int iW = 0; iW < nbWires; ++iW ) { - wireEdges.splice(wireEdges.end(), wireEdges, - wireEdges.begin(), ++wireEdges.begin()); - if ( from->IsSame( wireEdges.front() )) - return error(COMPERR_BAD_INPUT_MESH,"No nodes on vertices"); + StdMeshers_FaceSidePtr wire = wires[ iW ]; + _edgeLength += wire->Length(); + nbSegments += wire->NbSegments(); } - StdMeshers_FaceSide* wire = new StdMeshers_FaceSide( F, wireEdges, &aMesh, - true, ignoreMediumNodes); - wires[ iW ] = StdMeshers_FaceSidePtr( wire ); - if (_hypLengthFromEdges && wire->NbSegments() ) - _edgeLength += wire->Length() / wire->NbSegments(); - from = to; + if ( nbSegments ) + _edgeLength /= nbSegments; } - if ( wires[0]->NbSegments() < 3 ) // ex: a circle with 2 segments - return error(COMPERR_BAD_INPUT_MESH, - SMESH_Comment("Too few segments")<NbSegments()); if (_hypLengthFromEdges && _edgeLength < DBL_MIN ) _edgeLength = 100; @@ -502,22 +489,19 @@ bool StdMeshers_MEFISTO_2D::LoadPoints(TWireVector & wires, VWMap.Clear(); // wires have no common vertices } - const bool isXConst = false; // meaningles here - const double constValue = 0; // meaningles here - int m = 0; list< int > mOnVertex; for ( int iW = 0; iW < wires.size(); ++iW ) { - const vector& uvPtVec = wires[ iW ]->GetUVPtStruct(isXConst,constValue); + const vector& uvPtVec = wires[ iW ]->GetUVPtStruct(); if ( uvPtVec.size() != wires[ iW ]->NbPoints() ) { return error(COMPERR_BAD_INPUT_MESH,SMESH_Comment("Unexpected nb of points on wire ") << iW << uvPtVec.size()<<" != "<NbPoints()); } if ( m + uvPtVec.size()-1 > mefistoToDS.size() ) { MESSAGE("Wrong mefistoToDS.size: "<::const_iterator uvPt = uvPtVec.begin(); diff --git a/src/StdMeshers/StdMeshers_Prism_3D.cxx b/src/StdMeshers/StdMeshers_Prism_3D.cxx index 8d87d043f..6d28721e3 100644 --- a/src/StdMeshers/StdMeshers_Prism_3D.cxx +++ b/src/StdMeshers/StdMeshers_Prism_3D.cxx @@ -101,7 +101,7 @@ namespace { const SMDS_MeshNode* & node1, const SMDS_MeshNode* & node2) { - if ( param == 1.0 || column->size() == 1) { + if ( param >= 1.0 || column->size() == 1) { node1 = node2 = column->back(); return 0; } @@ -185,7 +185,7 @@ bool StdMeshers_Prism_3D::CheckHypothesis(SMESH_Mesh& a SMESH_Hypothesis::Hypothesis_Status& aStatus) { // Check shape geometry - +/* PAL16229 aStatus = SMESH_Hypothesis::HYP_BAD_GEOMETRY; // find not quadrangle faces @@ -216,7 +216,7 @@ bool StdMeshers_Prism_3D::CheckHypothesis(SMESH_Mesh& a if ( nbFace != nbEdge + 2 ) RETURN_BAD_RESULT("Bad nb of faces: " << nbFace << " but must be " << nbEdge + 2); } - +*/ // no hypothesis aStatus = SMESH_Hypothesis::HYP_OK; return true; @@ -275,17 +275,20 @@ bool StdMeshers_Prism_3D::Compute(SMESH_Mesh& theMesh, const TopoDS_Shape& theSh TNodeColumn& column = bot_column->second; // bottom node parameters and coords - gp_XYZ botParams = tBotNode.GetParams(); myShapeXYZ[ ID_BOT_FACE ] = tBotNode.GetCoords(); + gp_XYZ botParams = tBotNode.GetParams(); // compute top node parameters - gp_XYZ topParams; myShapeXYZ[ ID_TOP_FACE ] = gpXYZ( column.back() ); - gp_Pnt topCoords = myShapeXYZ[ ID_TOP_FACE ]; - if ( !myBlock.ComputeParameters( topCoords, topParams, ID_TOP_FACE )) - return error(dfltErr(),TCom("Can't compute normalized parameters ") - << "for node " << column.back()->GetID() - << " on the face #"<< column.back()->GetPosition()->GetShapeId() ); + gp_XYZ topParams = botParams; + topParams.SetZ( 1 ); + if ( column.size() > 2 ) { + gp_Pnt topCoords = myShapeXYZ[ ID_TOP_FACE ]; + if ( !myBlock.ComputeParameters( topCoords, topParams, ID_TOP_FACE, topParams )) + return error(TCom("Can't compute normalized parameters ") + << "for node " << column.back()->GetID() + << " on the face #"<< column.back()->GetPosition()->GetShapeId() ); + } // vertical loop TNodeColumn::iterator columnNodes = column.begin(); @@ -311,7 +314,11 @@ bool StdMeshers_Prism_3D::Compute(SMESH_Mesh& theMesh, const TopoDS_Shape& theSh // compute coords for a new node gp_XYZ coords; if ( !SMESH_Block::ShellPoint( params, myShapeXYZ, coords )) - return error(dfltErr(),"Can't compute coordinates by normalized parameters"); + return error("Can't compute coordinates by normalized parameters"); + + SHOWYXZ("TOPFacePoint ",myShapeXYZ[ ID_TOP_FACE]); + SHOWYXZ("BOT Node "<< tBotNode.myNode->GetID(),gpXYZ(tBotNode.myNode)); + SHOWYXZ("ShellPoint ",coords); // create a node node = meshDS->AddNode( coords.X(), coords.Y(), coords.Z() ); @@ -344,13 +351,13 @@ bool StdMeshers_Prism_3D::Compute(SMESH_Mesh& theMesh, const TopoDS_Shape& theSh if ( n->GetPosition()->GetTypeOfPosition() == SMDS_TOP_FACE ) { bot_column = myBotToColumnMap.find( n ); if ( bot_column == myBotToColumnMap.end() ) - return error(dfltErr(),TCom("No nodes found above node ") << n->GetID() ); + return error(TCom("No nodes found above node ") << n->GetID() ); columns[ i ] = & bot_column->second; } else { columns[ i ] = myBlock.GetNodeColumn( n ); if ( !columns[ i ] ) - return error(dfltErr(),TCom("No side nodes found above node ") << n->GetID() ); + return error(TCom("No side nodes found above node ") << n->GetID() ); } } // create prisms @@ -376,12 +383,44 @@ void StdMeshers_Prism_3D::AddPrisms( vector & columns, int shapeID = helper->GetSubShapeID(); int nbNodes = columns.size(); + int nbZ = columns[0]->size(); + if ( nbZ < 2 ) return; + + // find out orientation + bool isForward = true; + SMDS_VolumeTool vTool; + int z = 1; + switch ( nbNodes ) { + case 3: { + const SMDS_MeshNode* botNodes[3] = { (*columns[0])[z-1], + (*columns[1])[z-1], + (*columns[2])[z-1] }; + const SMDS_MeshNode* topNodes[3] = { (*columns[0])[z], + (*columns[1])[z], + (*columns[2])[z] }; + SMDS_VolumeOfNodes tmpVol ( botNodes[0], botNodes[1], botNodes[2], + topNodes[0], topNodes[1], topNodes[2]); + vTool.Set( &tmpVol ); + isForward = vTool.IsForward(); + break; + } + case 4: { + const SMDS_MeshNode* botNodes[4] = { (*columns[0])[z-1], (*columns[1])[z-1], + (*columns[2])[z-1], (*columns[3])[z-1] }; + const SMDS_MeshNode* topNodes[4] = { (*columns[0])[z], (*columns[1])[z], + (*columns[2])[z], (*columns[3])[z] }; + SMDS_VolumeOfNodes tmpVol ( botNodes[0], botNodes[1], botNodes[2], botNodes[3], + topNodes[0], topNodes[1], topNodes[2], topNodes[3]); + vTool.Set( &tmpVol ); + isForward = vTool.IsForward(); + break; + } + } // vertical loop on columns - for ( int z = 1; z < columns[0]->size(); ++z) + for ( z = 1; z < nbZ; ++z ) { SMDS_MeshElement* vol = 0; - SMDS_VolumeTool vTool; switch ( nbNodes ) { case 3: { @@ -391,11 +430,7 @@ void StdMeshers_Prism_3D::AddPrisms( vector & columns, const SMDS_MeshNode* topNodes[3] = { (*columns[0])[z], (*columns[1])[z], (*columns[2])[z] }; - // assure good orientation - SMDS_VolumeOfNodes tmpVol ( botNodes[0], botNodes[1], botNodes[2], - topNodes[0], topNodes[1], topNodes[2]); - vTool.Set( &tmpVol ); - if ( vTool.IsForward() ) + if ( isForward ) vol = helper->AddVolume( botNodes[0], botNodes[1], botNodes[2], topNodes[0], topNodes[1], topNodes[2]); else @@ -408,11 +443,7 @@ void StdMeshers_Prism_3D::AddPrisms( vector & columns, (*columns[2])[z-1], (*columns[3])[z-1] }; const SMDS_MeshNode* topNodes[4] = { (*columns[0])[z], (*columns[1])[z], (*columns[2])[z], (*columns[3])[z] }; - // assure good orientation - SMDS_VolumeOfNodes tmpVol ( botNodes[0], botNodes[1], botNodes[2], botNodes[3], - topNodes[0], topNodes[1], topNodes[2], topNodes[3]); - vTool.Set( &tmpVol ); - if ( vTool.IsForward() ) + if ( isForward ) vol = helper->AddVolume( botNodes[0], botNodes[1], botNodes[2], botNodes[3], topNodes[0], topNodes[1], topNodes[2], topNodes[3]); else @@ -462,7 +493,7 @@ bool StdMeshers_Prism_3D::assocOrProjBottom2Top() SMESHDS_SubMesh * topSMDS = topSM->GetSubMeshDS(); if ( !botSMDS || botSMDS->NbElements() == 0 ) - return error(dfltErr(),TCom("No elememts on face #") << botSM->GetId()); + return error(TCom("No elememts on face #") << botSM->GetId()); bool needProject = false; if ( !topSMDS || @@ -470,13 +501,13 @@ bool StdMeshers_Prism_3D::assocOrProjBottom2Top() botSMDS->NbNodes() != topSMDS->NbNodes()) { if ( myBlock.HasNotQuadElemOnTop() ) - return error(dfltErr(),TCom("Mesh on faces #") << botSM->GetId() + return error(TCom("Mesh on faces #") << botSM->GetId() <<" and #"<< topSM->GetId() << " seems different" ); needProject = true; } if ( 0/*needProject && !myProjectTriangles*/ ) - return error(dfltErr(),TCom("Mesh on faces #") << botSM->GetId() + return error(TCom("Mesh on faces #") << botSM->GetId() <<" and #"<< topSM->GetId() << " seems different" ); ///RETURN_BAD_RESULT("Need to project but not allowed"); @@ -492,7 +523,7 @@ bool StdMeshers_Prism_3D::assocOrProjBottom2Top() if ( !TAssocTool::FindSubShapeAssociation( botFace, myBlock.Mesh(), topFace, myBlock.Mesh(), shape2ShapeMap) ) - return error(dfltErr(),TCom("Topology of faces #") << botSM->GetId() + return error(TCom("Topology of faces #") << botSM->GetId() <<" and #"<< topSM->GetId() << " seems different" ); // Find matching nodes of top and bottom faces @@ -500,12 +531,13 @@ bool StdMeshers_Prism_3D::assocOrProjBottom2Top() if ( ! TAssocTool::FindMatchingNodesOnFaces( botFace, myBlock.Mesh(), topFace, myBlock.Mesh(), shape2ShapeMap, n2nMap )) - return error(dfltErr(),TCom("Mesh on faces #") << botSM->GetId() + return error(TCom("Mesh on faces #") << botSM->GetId() <<" and #"<< topSM->GetId() << " seems different" ); // Fill myBotToColumnMap int zSize = myBlock.VerticalSize(); + TNode prevTNode; TNodeNodeMap::iterator bN_tN = n2nMap.begin(); for ( ; bN_tN != n2nMap.end(); ++bN_tN ) { @@ -515,9 +547,16 @@ bool StdMeshers_Prism_3D::assocOrProjBottom2Top() continue; // wall columns are contained in myBlock // compute bottom node params TNode bN( botNode ); - if ( !myBlock.ComputeParameters( bN.GetCoords(), bN.ChangeParams(), ID_BOT_FACE )) - return error(dfltErr(),TCom("Can't compute normalized parameters ") - << "for node " << botNode->GetID() << " on the face #"<< botSM->GetId() ); + if ( zSize > 2 ) { + gp_XYZ paramHint(-1,-1,-1); + if ( prevTNode.IsNeighbor( bN )) + paramHint = prevTNode.GetParams(); + if ( !myBlock.ComputeParameters( bN.GetCoords(), bN.ChangeParams(), + ID_BOT_FACE, paramHint )) + return error(TCom("Can't compute normalized parameters for node ") + << botNode->GetID() << " on the face #"<< botSM->GetId() ); + prevTNode = bN; + } // create node column TNode2ColumnMap::iterator bN_col = myBotToColumnMap.insert( make_pair ( bN, TNodeColumn() )).first; @@ -555,6 +594,7 @@ bool StdMeshers_Prism_3D::projectBottomToTop() // Fill myBotToColumnMap int zSize = myBlock.VerticalSize(); + TNode prevTNode; SMDS_NodeIteratorPtr nIt = botSMDS->GetNodes(); while ( nIt->more() ) { @@ -563,15 +603,20 @@ bool StdMeshers_Prism_3D::projectBottomToTop() continue; // strange // compute bottom node params TNode bN( botNode ); - if ( !myBlock.ComputeParameters( bN.GetCoords(), bN.ChangeParams(), ID_BOT_FACE )) - return error(dfltErr(),TCom("Can't compute normalized parameters ") - << "for node " << botNode->GetID() << " on the face #"<< botSM->GetId() ); + gp_XYZ paramHint(-1,-1,-1); + if ( prevTNode.IsNeighbor( bN )) + paramHint = prevTNode.GetParams(); + if ( !myBlock.ComputeParameters( bN.GetCoords(), bN.ChangeParams(), + ID_BOT_FACE, paramHint )) + return error(TCom("Can't compute normalized parameters for node ") + << botNode->GetID() << " on the face #"<< botSM->GetId() ); + prevTNode = bN; // compute top node coords gp_XYZ topXYZ; gp_XY topUV; if ( !myBlock.FacePoint( ID_TOP_FACE, bN.GetParams(), topXYZ ) || !myBlock.FaceUV ( ID_TOP_FACE, bN.GetParams(), topUV )) - return error(dfltErr(),TCom("Can't compute coordinates ") - << "by normalized parameters on the face #"<< topSM->GetId() ); + return error(TCom("Can't compute coordinates " + "by normalized parameters on the face #")<< topSM->GetId() ); SMDS_MeshNode * topNode = meshDS->AddNode( topXYZ.X(),topXYZ.Y(),topXYZ.Z() ); meshDS->SetNodeOnFace( topNode, topFaceID, topUV.X(), topUV.Y() ); // create node column @@ -604,13 +649,13 @@ bool StdMeshers_Prism_3D::projectBottomToTop() if ( n->GetPosition()->GetTypeOfPosition() == SMDS_TOP_FACE ) { TNode2ColumnMap::iterator bot_column = myBotToColumnMap.find( n ); if ( bot_column == myBotToColumnMap.end() ) - return error(dfltErr(),TCom("No nodes found above node ") << n->GetID() ); + return error(TCom("No nodes found above node ") << n->GetID() ); nodes[ i ] = bot_column->second.back(); } else { const TNodeColumn* column = myBlock.GetNodeColumn( n ); if ( !column ) - return error(dfltErr(),TCom("No side nodes found above node ") << n->GetID() ); + return error(TCom("No side nodes found above node ") << n->GetID() ); nodes[ i ] = column->back(); } } @@ -673,6 +718,23 @@ bool StdMeshers_Prism_3D::setFaceAndEdgesXYZ( const int faceID, const gp_XYZ& pa return true; } +//================================================================================ +/*! + * \brief Return true if this node and other one belong to one face + */ +//================================================================================ + +bool TNode::IsNeighbor( const TNode& other ) const +{ + if ( !other.myNode || !myNode ) return false; + + SMDS_ElemIteratorPtr fIt = other.myNode->GetInverseElementIterator(SMDSAbs_Face); + while ( fIt->more() ) + if ( fIt->next()->GetNodeIndex( myNode ) >= 0 ) + return true; + return false; +} + //================================================================================ /*! * \brief Constructor. Initialization is needed @@ -813,11 +875,11 @@ bool StdMeshers_PrismAsBlock::Init(SMESH_MesherHelper* helper, // detect bad cases if ( nbNotQuad > 0 && nbNotQuad != 2 ) return error(COMPERR_BAD_SHAPE, - TCom("More than 2 not quadrilateral faces") + TCom("More than 2 not quadrilateral faces: ") < 2 ) return error(COMPERR_BAD_INPUT_MESH, - TCom("More then 2 faces meshed with not quadrangle elements") + TCom("More than 2 faces with not quadrangle elements: ") <Surface(), pcurves, isForward ); - SHOWYXZ( endl<<"F "<< iF << " id " << fID << " FRW " << sideFace->IsForward(), ); + SHOWYXZ( endl<<"F "<< iF << " id " << fID << " FRW " << sideFace->IsForward(), sideFace->Value(0,0)); // edges 3D geometry vector< int > edgeIdVec; SMESH_Block::GetFaceEdgesIDs( fID, edgeIdVec ); diff --git a/src/StdMeshers/StdMeshers_Prism_3D.hxx b/src/StdMeshers/StdMeshers_Prism_3D.hxx index 564919937..d6fab7b38 100644 --- a/src/StdMeshers/StdMeshers_Prism_3D.hxx +++ b/src/StdMeshers/StdMeshers_Prism_3D.hxx @@ -79,10 +79,12 @@ struct TNode gp_XYZ GetCoords() const { return gp_XYZ( myNode->X(), myNode->Y(), myNode->Z() ); } gp_XYZ GetParams() const { return myParams; } gp_XYZ& ChangeParams() { return myParams; } + bool HasParams() const { return myParams.X() >= 0.0; } SMDS_TypeOfPosition GetPositionType() const { return myNode ? myNode->GetPosition()->GetTypeOfPosition() : SMDS_TOP_UNSPEC; } + bool IsNeighbor( const TNode& other ) const; - TNode(const SMDS_MeshNode* node = 0): myNode(node) {} + TNode(const SMDS_MeshNode* node = 0): myNode(node), myParams(-1,-1,-1) {} bool operator < (const TNode& other) const { return myNode < other.myNode; } }; diff --git a/src/StdMeshers/StdMeshers_ProjectionUtils.cxx b/src/StdMeshers/StdMeshers_ProjectionUtils.cxx index c276b3afa..1452599ed 100644 --- a/src/StdMeshers/StdMeshers_ProjectionUtils.cxx +++ b/src/StdMeshers/StdMeshers_ProjectionUtils.cxx @@ -146,10 +146,11 @@ namespace { * \param edges2 - matching edges of another face * \param theMesh1 - mesh 1 * \param theMesh2 - mesh 2 + * \retval bool - true if association was fixed */ //================================================================================ - void FixAssocByPropagation( const int nbEdges, + bool FixAssocByPropagation( const int nbEdges, list< TopoDS_Edge > & edges1, list< TopoDS_Edge > & edges2, SMESH_Mesh* theMesh1, @@ -159,10 +160,13 @@ namespace { { list< TopoDS_Edge >::iterator eIt2 = ++edges2.begin(); // 2nd edge of the 2nd face TopoDS_Edge edge2 = - StdMeshers_ProjectionUtils::GetPropagationEdge( theMesh1, *eIt2, edges1.front() ); - if ( !edge2.IsNull() ) // propagation found for the second edge + StdMeshers_ProjectionUtils::GetPropagationEdge( theMesh1, *eIt2, edges1.front() ).second; + if ( !edge2.IsNull() ) { // propagation found for the second edge Reverse( edges2, nbEdges ); + return true; + } } + return false; } } @@ -330,15 +334,21 @@ bool StdMeshers_ProjectionUtils::FindSubShapeAssociation(const TopoDS_Shape& the list< TopoDS_Edge > edges1, edges2; int nbE = FindFaceAssociation( face1, VV1, face2, VV2, edges1, edges2 ); if ( !nbE ) RETURN_BAD_RESULT("FindFaceAssociation() failed"); - FixAssocByPropagation( nbE, edges1, edges2, theMesh1, theMesh2 ); - InsertAssociation( face1, face2, theMap, bidirect); // assoc faces + MESSAGE("Assoc FACE " << theMesh1->GetMeshDS()->ShapeToIndex( face1 )<< + " to " << theMesh2->GetMeshDS()->ShapeToIndex( face2 )); + if ( nbE == 2 && (edge1.IsSame( edges1.front())) != (edge2.IsSame( edges2.front()))) + { + Reverse( edges2, nbE ); + } list< TopoDS_Edge >::iterator eIt1 = edges1.begin(); list< TopoDS_Edge >::iterator eIt2 = edges2.begin(); for ( ; eIt1 != edges1.end(); ++eIt1, ++eIt2 ) { if ( !boundEdges.Add( *eIt1 )) continue; // already associated InsertAssociation( *eIt1, *eIt2, theMap, bidirect); // assoc edges + MESSAGE("Assoc edge " << theMesh1->GetMeshDS()->ShapeToIndex( *eIt1 )<< + " to " << theMesh2->GetMeshDS()->ShapeToIndex( *eIt2 )); VV1[0] = TopExp::FirstVertex( *eIt1, true ); VV2[0] = TopExp::FirstVertex( *eIt2, true ); InsertAssociation( VV1[0], VV2[0], theMap, bidirect); // assoc vertices @@ -372,7 +382,7 @@ bool StdMeshers_ProjectionUtils::FindSubShapeAssociation(const TopoDS_Shape& the TopoDS_Edge edge2 = TopoDS::Edge( theShape2 ); if ( IsPropagationPossible( theMesh1, theMesh2 )) { - TopoDS_Edge prpEdge = GetPropagationEdge( theMesh1, edge2, edge1 ); + TopoDS_Edge prpEdge = GetPropagationEdge( theMesh1, edge2, edge1 ).second; if ( !prpEdge.IsNull() ) { TopoDS_Vertex VV1[2], VV2[2]; @@ -405,40 +415,46 @@ bool StdMeshers_ProjectionUtils::FindSubShapeAssociation(const TopoDS_Shape& the { TopoDS_Face face1 = TopoDS::Face(theShape1); TopoDS_Face face2 = TopoDS::Face(theShape2); + TopoDS_Edge edge1, edge2; // get outer edge of theShape1 - TopoDS_Edge edge1 = TopoDS::Edge( OuterShape( face1, TopAbs_EDGE )); + edge1 = TopoDS::Edge( OuterShape( face1, TopAbs_EDGE )); // find out if any edge of face2 is a propagation edge of outer edge1 + map propag_edges; // use map to find the closest propagation edge for ( TopExp_Explorer exp( face2, TopAbs_EDGE ); exp.More(); exp.Next() ) { - TopoDS_Edge edge2 = TopoDS::Edge( exp.Current() ); - edge2 = GetPropagationEdge( theMesh1, edge2, edge1 ); - if ( !edge2.IsNull() ) // propagation found + edge2 = TopoDS::Edge( exp.Current() ); + pair step_edge = GetPropagationEdge( theMesh1, edge2, edge1 ); + if ( !step_edge.second.IsNull() ) { // propagation found + propag_edges.insert( step_edge ); + } + } + if ( !propag_edges.empty() ) // propagation found + { + edge2 = propag_edges.begin()->second; + TopoDS_Vertex VV1[2], VV2[2]; + TopExp::Vertices( edge1, VV1[0], VV1[1], true ); + TopExp::Vertices( edge2, VV2[0], VV2[1], true ); + list< TopoDS_Edge > edges1, edges2; + int nbE = FindFaceAssociation( face1, VV1, face2, VV2, edges1, edges2 ); + if ( !nbE ) RETURN_BAD_RESULT("FindFaceAssociation() failed"); + if ( nbE == 2 ) // only 2 edges { - TopoDS_Vertex VV1[2], VV2[2]; - TopExp::Vertices( edge1, VV1[0], VV1[1], true ); - TopExp::Vertices( edge2, VV2[0], VV2[1], true ); - list< TopoDS_Edge > edges1, edges2; - int nbE = FindFaceAssociation( face1, VV1, face2, VV2, edges1, edges2 ); - if ( !nbE ) RETURN_BAD_RESULT("FindFaceAssociation() failed"); - if ( nbE == 2 ) // only 2 edges - { - // take care of proper association of propagated edges - bool same1 = edge1.IsSame( edges1.front() ); - bool same2 = edge2.IsSame( edges2.front() ); - if ( same1 != same2 ) - Reverse(edges2, nbE); - } - // store association - list< TopoDS_Edge >::iterator eIt1 = edges1.begin(); - list< TopoDS_Edge >::iterator eIt2 = edges2.begin(); - for ( ; eIt1 != edges1.end(); ++eIt1, ++eIt2 ) - { - InsertAssociation( *eIt1, *eIt2, theMap, bidirect); - VV1[0] = TopExp::FirstVertex( *eIt1, true ); - VV2[0] = TopExp::FirstVertex( *eIt2, true ); - InsertAssociation( VV1[0], VV2[0], theMap, bidirect); - } - return true; + // take care of proper association of propagated edges + bool same1 = edge1.IsSame( edges1.front() ); + bool same2 = edge2.IsSame( edges2.front() ); + if ( same1 != same2 ) + Reverse(edges2, nbE); } + // store association + list< TopoDS_Edge >::iterator eIt1 = edges1.begin(); + list< TopoDS_Edge >::iterator eIt2 = edges2.begin(); + for ( ; eIt1 != edges1.end(); ++eIt1, ++eIt2 ) + { + InsertAssociation( *eIt1, *eIt2, theMap, bidirect); + VV1[0] = TopExp::FirstVertex( *eIt1, true ); + VV2[0] = TopExp::FirstVertex( *eIt2, true ); + InsertAssociation( VV1[0], VV2[0], theMap, bidirect); + } + return true; } } break; // try by vertex closeness @@ -568,6 +584,7 @@ int StdMeshers_ProjectionUtils::FindFaceAssociation(const TopoDS_Face& face1, list< TopoDS_Edge >::iterator eBackIt; if ( !VV1[1].IsSame( TopExp::LastVertex( edges1.front(), true ))) { + reverse = true; eBackIt = --edges1.end(); // check if the second vertex belongs to the first or last edge in the wire if ( !VV1[1].IsSame( TopExp::FirstVertex( *eBackIt, true ))) { @@ -580,10 +597,10 @@ int StdMeshers_ProjectionUtils::FindFaceAssociation(const TopoDS_Face& face1, if ( KO ) RETURN_BAD_RESULT("GetOrderedEdges() failed"); } - reverse = true; } eBackIt = --edges2.end(); if ( !VV2[1].IsSame( TopExp::LastVertex( edges2.front(), true ))) { + reverse = !reverse; // check if the second vertex belongs to the first or last edge in the wire if ( !VV2[1].IsSame( TopExp::FirstVertex( *eBackIt, true ))) { bool KO = true; // belongs to none @@ -595,7 +612,6 @@ int StdMeshers_ProjectionUtils::FindFaceAssociation(const TopoDS_Face& face1, if ( KO ) RETURN_BAD_RESULT("GetOrderedEdges() failed"); } - reverse = !reverse; } if ( reverse ) { @@ -762,23 +778,25 @@ TopoDS_Face StdMeshers_ProjectionUtils::GetNextFace( SMESH_Mesh* mesh, * \param aMesh - mesh * \param theEdge - edge to find by propagation * \param fromEdge - start edge for propagation - * \retval TopoDS_Edge - found edge + * \retval pair - propagation step and found edge */ //================================================================================ -TopoDS_Edge StdMeshers_ProjectionUtils::GetPropagationEdge( SMESH_Mesh* aMesh, - const TopoDS_Edge& theEdge, - const TopoDS_Edge& fromEdge) +pair +StdMeshers_ProjectionUtils::GetPropagationEdge( SMESH_Mesh* aMesh, + const TopoDS_Edge& theEdge, + const TopoDS_Edge& fromEdge) { SMESH_IndexedMapOfShape aChain; - //aChain.Add(fromEdge); + int step = 0; // List of edges, added to chain on the previous cycle pass TopTools_ListOfShape listPrevEdges; - listPrevEdges.Append(fromEdge/*.Oriented( TopAbs_FORWARD )*/); + listPrevEdges.Append(fromEdge); // Collect all edges pass by pass while (listPrevEdges.Extent() > 0) { + step++; // List of edges, added to chain on this cycle pass TopTools_ListOfShape listCurEdges; @@ -823,7 +841,7 @@ TopoDS_Edge StdMeshers_ProjectionUtils::GetPropagationEdge( SMESH_Mesh* a ori = TopAbs::Reverse( ori ); anOppE.Orientation( ori ); if ( anOppE.IsSame( theEdge )) - return TopoDS::Edge( anOppE ); + return make_pair( step, TopoDS::Edge( anOppE )); aChain.Add(anOppE); listCurEdges.Append(anOppE); } @@ -835,7 +853,7 @@ TopoDS_Edge StdMeshers_ProjectionUtils::GetPropagationEdge( SMESH_Mesh* a listPrevEdges = listCurEdges; } // while (listPrevEdges.Extent() > 0) - return TopoDS_Edge(); + return make_pair( INT_MAX, TopoDS_Edge()); } //================================================================================ @@ -888,33 +906,50 @@ FindMatchingNodesOnFaces( const TopoDS_Face& face1, // 1. Nodes of corresponding links: - // get 2 matching edges, not seam ones - TopoDS_Edge edge1, edge2; + // get 2 matching edges, try to find not seam ones + TopoDS_Edge edge1, edge2, seam1, seam2; TopExp_Explorer eE( OuterShape( face2, TopAbs_WIRE ), TopAbs_EDGE ); do { - edge2 = TopoDS::Edge( eE.Current() ); + // edge 2 + TopoDS_Edge e2 = TopoDS::Edge( eE.Current() ); eE.Next(); - } while ( BRep_Tool::IsClosed( edge2, face2 ) && eE.More()); - if ( !assocMap.IsBound( edge2 )) - RETURN_BAD_RESULT("Association not found for edge " << meshDS2->ShapeToIndex( edge2 )); - edge1 = TopoDS::Edge( assocMap( edge2 )); - if ( !IsSubShape( edge1, face1 )) - RETURN_BAD_RESULT("Wrong association, edge " << meshDS1->ShapeToIndex( edge1 ) << - " isn't a subshape of face " << meshDS1->ShapeToIndex( face1 )); + // edge 1 + if ( !assocMap.IsBound( e2 )) + RETURN_BAD_RESULT("Association not found for edge " << meshDS2->ShapeToIndex( e2 )); + TopoDS_Edge e1 = TopoDS::Edge( assocMap( e2 )); + if ( !IsSubShape( e1, face1 )) + RETURN_BAD_RESULT("Wrong association, edge " << meshDS1->ShapeToIndex( e1 ) << + " isn't a subshape of face " << meshDS1->ShapeToIndex( face1 )); + // check that there are nodes on edges + SMESHDS_SubMesh * eSM1 = meshDS1->MeshElements( e1 ); + SMESHDS_SubMesh * eSM2 = meshDS2->MeshElements( e2 ); + if ( eSM1 && eSM2 && eSM1->NbNodes() > 0 && eSM2->NbNodes() > 0 ) + { + if ( BRep_Tool::IsClosed( e2, face2 )) { + seam1 = e1; seam2 = e2; + } + else { + edge1 = e1; edge2 = e2; + } + } + } while ( edge2.IsNull() && eE.More() ); + // + if ( edge2.IsNull() ) { + edge1 = seam1; edge2 = seam2; + } + if ( edge2.IsNull() ) RETURN_BAD_RESULT("No matching edges with nodes found"); // get 2 matching vertices - TopoDS_Shape V2 = TopExp::FirstVertex( TopoDS::Edge( edge2 )); + TopoDS_Vertex V2 = TopExp::FirstVertex( TopoDS::Edge( edge2 )); if ( !assocMap.IsBound( V2 )) RETURN_BAD_RESULT("Association not found for vertex " << meshDS2->ShapeToIndex( V2 )); - TopoDS_Shape V1 = assocMap( V2 ); + TopoDS_Vertex V1 = TopoDS::Vertex( assocMap( V2 )); // nodes on vertices - SMESHDS_SubMesh * vSM1 = meshDS1->MeshElements( V1 ); - SMESHDS_SubMesh * vSM2 = meshDS2->MeshElements( V2 ); - if ( !vSM1 || !vSM2 || vSM1->NbNodes() != 1 || vSM2->NbNodes() != 1 ) - RETURN_BAD_RESULT("Bad node submesh"); - const SMDS_MeshNode* vNode1 = vSM1->GetNodes()->next(); - const SMDS_MeshNode* vNode2 = vSM2->GetNodes()->next(); + const SMDS_MeshNode* vNode1 = SMESH_Algo::VertexNode( V1, meshDS1 ); + const SMDS_MeshNode* vNode2 = SMESH_Algo::VertexNode( V2, meshDS2 ); + if ( !vNode1 ) RETURN_BAD_RESULT("No node on vertex #" << meshDS1->ShapeToIndex( V1 )); + if ( !vNode2 ) RETURN_BAD_RESULT("No node on vertex #" << meshDS2->ShapeToIndex( V2 )); // nodes on edges linked with nodes on vertices const SMDS_MeshNode* nullNode = 0; @@ -1020,6 +1055,18 @@ FindMatchingNodesOnFaces( const TopoDS_Face& face1, if ( !onBnd ) elems.insert( f ); } + // add also faces adjacent to faceToKeep + int nbNodes = faceToKeep->NbNodes(); + if ( faceToKeep->IsQuadratic() ) nbNodes /= 2; + notInSet.insert( f1 ); + notInSet.insert( f2 ); + for ( int i = 0; i < nbNodes; ++i ) { + const SMDS_MeshNode* n1 = faceToKeep->GetNode( i ); + const SMDS_MeshNode* n2 = faceToKeep->GetNode( i+1 ); + f1 = SMESH_MeshEditor::FindFaceInSet( n1, n2, inSet, notInSet ); + if ( f1 ) + elems.insert( f1 ); + } } // case on a sphere } // loop on 2 faces @@ -1083,13 +1130,11 @@ FindMatchingNodesOnFaces( const TopoDS_Face& face1, V2 = TopExp::LastVertex( TopoDS::Edge( edge2 )); if ( !assocMap.IsBound( V2 )) RETURN_BAD_RESULT("Association not found for vertex " << meshDS2->ShapeToIndex( V2 )); - V1 = assocMap( V2 ); - vSM1 = meshDS1->MeshElements( V1 ); - vSM2 = meshDS2->MeshElements( V2 ); - if ( !vSM1 || !vSM2 || vSM1->NbNodes() != 1 || vSM2->NbNodes() != 1 ) - RETURN_BAD_RESULT("Bad node submesh"); - vNode1 = vSM1->GetNodes()->next(); - vNode2 = vSM2->GetNodes()->next(); + V1 = TopoDS::Vertex( assocMap( V2 )); + vNode1 = SMESH_Algo::VertexNode( V1, meshDS1 ); + vNode2 = SMESH_Algo::VertexNode( V2, meshDS2 ); + if ( !vNode1 ) RETURN_BAD_RESULT("No node on vertex #" << meshDS1->ShapeToIndex( V1 )); + if ( !vNode2 ) RETURN_BAD_RESULT("No node on vertex #" << meshDS2->ShapeToIndex( V2 )); node1To2Map.insert( make_pair( vNode1, vNode2 )); } diff --git a/src/StdMeshers/StdMeshers_ProjectionUtils.hxx b/src/StdMeshers/StdMeshers_ProjectionUtils.hxx index 53064e7f1..ca57f556a 100644 --- a/src/StdMeshers/StdMeshers_ProjectionUtils.hxx +++ b/src/StdMeshers/StdMeshers_ProjectionUtils.hxx @@ -139,11 +139,11 @@ class STDMESHERS_EXPORT StdMeshers_ProjectionUtils * \brief Return an oriented propagation edge * \param aMesh - mesh * \param fromEdge - start edge for propagation - * \retval TopoDS_Edge - found edge + * \retval pair - propagation step and found edge */ - static TopoDS_Edge GetPropagationEdge( SMESH_Mesh* aMesh, - const TopoDS_Edge& anEdge, - const TopoDS_Edge& fromEdge); + static std::pair GetPropagationEdge( SMESH_Mesh* aMesh, + const TopoDS_Edge& anEdge, + const TopoDS_Edge& fromEdge); /*! * \brief Find corresponding nodes on two faces diff --git a/src/StdMeshers/StdMeshers_Projection_1D.cxx b/src/StdMeshers/StdMeshers_Projection_1D.cxx index 1bfdc41c5..d3d292575 100644 --- a/src/StdMeshers/StdMeshers_Projection_1D.cxx +++ b/src/StdMeshers/StdMeshers_Projection_1D.cxx @@ -191,7 +191,7 @@ bool StdMeshers_Projection_1D::Compute(SMESH_Mesh& theMesh, const TopoDS_Shape& TAssocTool::InitVertexAssociation( _sourceHypo, shape2ShapeMap ); if ( !TAssocTool::FindSubShapeAssociation( tgtEdge, tgtMesh, srcEdge, srcMesh, shape2ShapeMap) ) - return error(dfltErr(),SMESH_Comment("Vertices association failed" )); + return error(SMESH_Comment("Vertices association failed" )); // ---------------------------------------------- // Assure that mesh on a source edge is computed @@ -275,7 +275,7 @@ bool StdMeshers_Projection_1D::Compute(SMESH_Mesh& theMesh, const TopoDS_Shape& // from the point at given parameter. GCPnts_AbscissaPoint Discret( curveAdaptor, dl * lengths[ i-1 ], tgtParams[ i-1 ] ); if ( !Discret.IsDone() ) - return error(dfltErr(),"GCPnts_AbscissaPoint failed"); + return error("GCPnts_AbscissaPoint failed"); tgtParams[ i ] = Discret.Parameter(); } // make internal nodes diff --git a/src/StdMeshers/StdMeshers_Projection_2D.cxx b/src/StdMeshers/StdMeshers_Projection_2D.cxx index 4aa83bdd0..687ccc4af 100644 --- a/src/StdMeshers/StdMeshers_Projection_2D.cxx +++ b/src/StdMeshers/StdMeshers_Projection_2D.cxx @@ -439,11 +439,6 @@ bool StdMeshers_Projection_2D::Compute(SMESH_Mesh& theMesh, const TopoDS_Shape& { TopoDS_Edge srcE1 = srcEdges.front(), tgtE1 = tgtEdges.front(); reverse = ( ! srcE1.IsSame( shape2ShapeMap( tgtE1 ))); - if ( BRep_Tool::IsClosed( tgtE1, tgtFace )) { - reverse = ( srcE1.Orientation() == tgtE1.Orientation() ); - if ( _sourceHypo->GetSourceFace().Orientation() != theShape.Orientation() ) - reverse = !reverse; - } } else if ( nbEdgesInWires.front() == 1 ) { @@ -463,18 +458,18 @@ bool StdMeshers_Projection_2D::Compute(SMESH_Mesh& theMesh, const TopoDS_Shape& mapper.Apply( tgtFace, tgtV1, reverse ); if ( mapper.GetErrorCode() != SMESH_Pattern::ERR_OK ) - return error(dfltErr(),"Can't apply source mesh pattern to the face"); + return error("Can't apply source mesh pattern to the face"); // Create the mesh const bool toCreatePolygons = false, toCreatePolyedrs = false; mapper.MakeMesh( tgtMesh, toCreatePolygons, toCreatePolyedrs ); if ( mapper.GetErrorCode() != SMESH_Pattern::ERR_OK ) - return error(dfltErr(),"Can't make mesh by source mesh pattern"); + return error("Can't make mesh by source mesh pattern"); // it will remove mesh built by pattern mapper on edges and vertices // in failure case - MeshCleaner cleaner( tgtSubMesh ); + // MeshCleaner cleaner( tgtSubMesh ); // ------------------------------------------------------------------------- // mapper doesn't take care of nodes already existing on edges and vertices, @@ -497,7 +492,7 @@ bool StdMeshers_Projection_2D::Compute(SMESH_Mesh& theMesh, const TopoDS_Shape& bool isSeam = helper.IsSeamShape( sm->GetId() ); - enum { NEW_NODES, OLD_NODES }; + enum { NEW_NODES = 0, OLD_NODES }; map< double, const SMDS_MeshNode* > u2nodesMaps[2], u2nodesOnSeam; map< double, const SMDS_MeshNode* >::iterator u_oldNode, u_newNode, u_newOnSeam, newEnd; set< const SMDS_MeshNode* > seamNodes; @@ -518,7 +513,7 @@ bool StdMeshers_Projection_2D::Compute(SMESH_Mesh& theMesh, const TopoDS_Shape& } // sort nodes on edges by its position - map< double, const SMDS_MeshNode* > & pos2nodes = u2nodesMaps[ isOld ]; + map< double, const SMDS_MeshNode* > & pos2nodes = u2nodesMaps[isOld ? OLD_NODES : NEW_NODES]; switch ( node->GetPosition()->GetTypeOfPosition() ) { case SMDS_TOP_VERTEX: { @@ -536,14 +531,22 @@ bool StdMeshers_Projection_2D::Compute(SMESH_Mesh& theMesh, const TopoDS_Shape& node->GetPosition()->GetTypeOfPosition()); } } - if ( u2nodesMaps[ OLD_NODES ].size() != u2nodesMaps[ NEW_NODES ].size() ) - RETURN_BAD_RESULT("Different nb of old and new nodes " << + if ( u2nodesMaps[ NEW_NODES ].size() != u2nodesMaps[ OLD_NODES ].size() ) + { + if ( u2nodesMaps[ NEW_NODES ].size() == 0 && + sm->GetSubShape().ShapeType() == TopAbs_EDGE && + BRep_Tool::Degenerated( TopoDS::Edge( sm->GetSubShape() ))) + // NPAL15894 (tt88bis.py) - project mesh built by NETGEN_1d_2D that + // does not make segments/nodes on degenerated edges + continue; + RETURN_BAD_RESULT("Different nb of old and new nodes on shape #"<< sm->GetId() <<" "<< u2nodesMaps[ OLD_NODES ].size() << " != " << u2nodesMaps[ NEW_NODES ].size()); - if ( isSeam && u2nodesMaps[ OLD_NODES ].size() != u2nodesOnSeam.size() ) + } + if ( isSeam && u2nodesMaps[ OLD_NODES ].size() != u2nodesOnSeam.size() ) { RETURN_BAD_RESULT("Different nb of old and seam nodes " << u2nodesMaps[ OLD_NODES ].size() << " != " << u2nodesOnSeam.size()); - + } // Make groups of nodes to merge u_oldNode = u2nodesMaps[ OLD_NODES ].begin(); u_newNode = u2nodesMaps[ NEW_NODES ].begin(); @@ -606,7 +609,7 @@ bool StdMeshers_Projection_2D::Compute(SMESH_Mesh& theMesh, const TopoDS_Shape& } } - cleaner.Release(); // do not remove mesh + //cleaner.Release(); // do not remove mesh return true; } diff --git a/src/StdMeshers/StdMeshers_Projection_3D.cxx b/src/StdMeshers/StdMeshers_Projection_3D.cxx index 68eda5d65..4a3d9a630 100644 --- a/src/StdMeshers/StdMeshers_Projection_3D.cxx +++ b/src/StdMeshers/StdMeshers_Projection_3D.cxx @@ -92,6 +92,7 @@ bool StdMeshers_Projection_3D::CheckHypothesis(SMESH_Mesh& SMESH_Hypothesis::Hypothesis_Status& aStatus) { // check aShape that must be a 6 faces block +/* PAL16229 if ( TAssocTool::Count( aShape, TopAbs_SHELL, 1 ) != 1 || TAssocTool::Count( aShape, TopAbs_FACE , 1 ) != 6 || TAssocTool::Count( aShape, TopAbs_EDGE , 1 ) != 12 || @@ -100,7 +101,7 @@ bool StdMeshers_Projection_3D::CheckHypothesis(SMESH_Mesh& aStatus = HYP_BAD_GEOMETRY; return false; } - +*/ list ::const_iterator itl; const list &hyps = GetUsedHypothesis(aMesh, aShape); @@ -206,14 +207,24 @@ bool StdMeshers_Projection_3D::Compute(SMESH_Mesh& aMesh, const TopoDS_Shape& aS srcShell = TopoDS::Shell( exp.Current() ); if ( nbShell != 1 ) return error(COMPERR_BAD_SHAPE, - SMESH_Comment("Shape must have 1 shell but not") << nbShell); + SMESH_Comment("Source shape must have 1 shell but not ") << nbShell); exp.Init( aShape, TopAbs_SHELL ); for ( nbShell = 0; exp.More(); exp.Next(), ++nbShell ) tgtShell = TopoDS::Shell( exp.Current() ); if ( nbShell != 1 ) return error(COMPERR_BAD_SHAPE, - SMESH_Comment("Shape must have 1 shell but not") << nbShell); + SMESH_Comment("Target shape must have 1 shell but not ") << nbShell); + + // Check that shapes are blocks + if ( TAssocTool::Count( tgtShell, TopAbs_FACE , 1 ) != 6 || + TAssocTool::Count( tgtShell, TopAbs_EDGE , 1 ) != 12 || + TAssocTool::Count( tgtShell, TopAbs_WIRE , 1 ) != 6 ) + return error(COMPERR_BAD_SHAPE, "Target shape is not a block"); + if ( TAssocTool::Count( srcShell, TopAbs_FACE , 1 ) != 6 || + TAssocTool::Count( srcShell, TopAbs_EDGE , 1 ) != 12 || + TAssocTool::Count( srcShell, TopAbs_WIRE , 1 ) != 6 ) + return error(COMPERR_BAD_SHAPE, "Source shape is not a block"); // Assure that mesh on a source shape is computed @@ -251,12 +262,12 @@ bool StdMeshers_Projection_3D::Compute(SMESH_Mesh& aMesh, const TopoDS_Shape& aS TopExp::Vertices( TopoDS::Edge( exp.Current() ), tgtV000, tgtV100 ); if ( !shape2ShapeMap.IsBound( tgtV000 ) || !shape2ShapeMap.IsBound( tgtV100 )) - return error(dfltErr(),"Association of subshapes failed" ); + return error("Association of subshapes failed" ); srcV000 = TopoDS::Vertex( shape2ShapeMap( tgtV000 )); srcV100 = TopoDS::Vertex( shape2ShapeMap( tgtV100 )); if ( !TAssocTool::IsSubShape( srcV000, srcShell ) || !TAssocTool::IsSubShape( srcV100, srcShell )) - return error(dfltErr(),"Incorrect association of subshapes" ); + return error("Incorrect association of subshapes" ); } // Load 2 SMESH_Block's with src and tgt shells @@ -342,12 +353,12 @@ bool StdMeshers_Projection_3D::Compute(SMESH_Mesh& aMesh, const TopoDS_Shape& aS gp_Pnt srcCoord = gpXYZ( srcNode ); gp_XYZ srcParam; if ( !srcBlock.ComputeParameters( srcCoord, srcParam )) - return error(dfltErr(),SMESH_Comment("Can't compute normalized parameters ") + return error(SMESH_Comment("Can't compute normalized parameters ") << "for source node " << srcNode->GetID()); // compute coordinates of target node by srcParam gp_XYZ tgtXYZ; if ( !tgtBlock.ShellPoint( srcParam, tgtXYZ )) - return error(dfltErr(),"Can't compute coordinates by normalized parameters"); + return error("Can't compute coordinates by normalized parameters"); // add node SMDS_MeshNode* newNode = tgtMeshDS->AddNode( tgtXYZ.X(), tgtXYZ.Y(), tgtXYZ.Z() ); tgtMeshDS->SetNodeInVolume( newNode, helper.GetSubShapeID() ); diff --git a/src/StdMeshers/StdMeshers_Propagation.cxx b/src/StdMeshers/StdMeshers_Propagation.cxx index 9bbab440e..306ae1830 100644 --- a/src/StdMeshers/StdMeshers_Propagation.cxx +++ b/src/StdMeshers/StdMeshers_Propagation.cxx @@ -28,10 +28,18 @@ #include "utilities.h" +#include "SMDS_SetIterator.hxx" +#include "SMESH_Algo.hxx" +#include "SMESH_HypoFilter.hxx" #include "SMESH_Mesh.hxx" #include "SMESH_subMesh.hxx" -#include "SMESH_HypoFilter.hxx" -#include "SMDS_SetIterator.hxx" + +#include +#include +#include + +#define DBGMSG(txt) \ +// cout << txt << endl; using namespace std; @@ -54,7 +62,7 @@ namespace { /*! * \brief Return an edge from which hypotheses are propagated from */ - static TopoDS_Edge GetSource(SMESH_subMesh * submesh) { return TopoDS_Edge(); }; + static TopoDS_Edge GetSource(SMESH_subMesh * submesh); /*! * \brief Does it's main job */ @@ -106,7 +114,7 @@ TopoDS_Edge StdMeshers_Propagation::GetPropagationSource(SMESH_Mesh& theMesh, namespace { - enum SubMeshState { WAIT_PROPAG_HYP, // no propagation hyp in chain + enum SubMeshState { WAIT_PROPAG_HYP, // propagation hyp or local 1D hyp is missing HAS_PROPAG_HYP, // propag hyp on this submesh IN_CHAIN, // submesh is in propagation chain LAST_IN_CHAIN, // submesh with local 1D hyp breaking a chain @@ -115,15 +123,24 @@ namespace { struct PropagationMgrData : public EventListenerData { bool myForward; //!< true if a curve of edge in chain is codirected with one of source edge - PropagationMgrData( SubMeshState state ): EventListenerData(true) { - myType = state; + PropagationMgrData( SubMeshState state=WAIT_PROPAG_HYP ): EventListenerData(true) { + myType = state; myForward = true; + } + void Init() { + myType = WAIT_PROPAG_HYP; mySubMeshes.clear(); myForward = true; } SubMeshState State() const { return (SubMeshState) myType; } + void SetState(SubMeshState state) { + myType = state; + } void SetSource(SMESH_subMesh* sm ) { mySubMeshes.clear(); if ( sm ) mySubMeshes.push_back( sm ); } + void AddSource(SMESH_subMesh* sm ) { + if ( sm ) mySubMeshes.push_back( sm ); + } void SetChain(list< SMESH_subMesh* >& chain ) { mySubMeshes.clear(); mySubMeshes.splice( mySubMeshes.end(), chain ); } @@ -131,16 +148,6 @@ namespace { SMESH_subMesh* GetSource() const; }; - //============================================================================= - /*! - * \brief return filter to find Propagation hypothesis - */ - SMESH_HypoFilter & propagHypFilter() - { - static SMESH_HypoFilter propagHypFilter - ( SMESH_HypoFilter::HasName( StdMeshers_Propagation::GetName ())); - return propagHypFilter; - } //============================================================================= /*! * \brief return static PropagationMgr @@ -156,9 +163,9 @@ namespace { } //============================================================================= /*! - * \brief return PropagationMgrData + * \brief return PropagationMgrData found on a submesh */ - PropagationMgrData* getData(SMESH_subMesh* sm) + PropagationMgrData* findData(SMESH_subMesh* sm) { if ( sm ) return static_cast< PropagationMgrData* >( sm->GetEventListenerData( getListener() )); @@ -166,57 +173,61 @@ namespace { } //============================================================================= /*! - * \brief return PropagationMgrData + * \brief return PropagationMgrData found on theEdge submesh */ - PropagationMgrData* getData(SMESH_Mesh& theMesh, const TopoDS_Shape& theEdge) + PropagationMgrData* findData(SMESH_Mesh& theMesh, const TopoDS_Shape& theEdge) { if ( theEdge.ShapeType() == TopAbs_EDGE ) - return getData( theMesh.GetSubMeshContaining( theEdge ) ); + return findData( theMesh.GetSubMeshContaining( theEdge ) ); return 0; } - //================================================================================ + //============================================================================= /*! - * \brief Return an iterator on a chain + * \brief return existing or a new PropagationMgrData */ - SMESH_subMeshIteratorPtr PropagationMgrData::GetChain() const + PropagationMgrData* getData(SMESH_subMesh* sm) { - typedef SMESH_subMesh* TsubMesh; - typedef SMDS_SetIterator< TsubMesh, list< TsubMesh >::const_iterator > TIterator; - switch ( State() ) { - case HAS_PROPAG_HYP: - return SMESH_subMeshIteratorPtr - ( new TIterator( mySubMeshes.begin(), mySubMeshes.end() )); - case IN_CHAIN: - case LAST_IN_CHAIN: - if ( mySubMeshes.empty() ) break; - return getData( mySubMeshes.front() )->GetChain(); - default:; + PropagationMgrData* data = findData( sm ); + if ( !data && sm ) { + data = new PropagationMgrData(); + sm->SetEventListener( getListener(), data, sm ); } - return SMESH_subMeshIteratorPtr - ( new TIterator( mySubMeshes.end(), mySubMeshes.end() )); + return data; } - //================================================================================ + //============================================================================= /*! - * \brief Return a propagation source submesh + * \brief Returns a local 1D hypothesis used for theEdge */ - SMESH_subMesh* PropagationMgrData::GetSource() const + const SMESH_Hypothesis* getLocal1DHyp (SMESH_Mesh& theMesh, + const TopoDS_Shape& theEdge) { - if ( myType == IN_CHAIN || myType == LAST_IN_CHAIN ) - if ( !mySubMeshes.empty() ) - return mySubMeshes.front(); - return 0; + static SMESH_HypoFilter hypo; + hypo.Init( hypo.HasDim( 1 )). + AndNot ( hypo.IsAlgo() ). + AndNot ( hypo.IsAssignedTo( theMesh.GetMeshDS()->ShapeToMesh() )); + return theMesh.GetHypothesis( theEdge, hypo, true ); } //============================================================================= /*! - * \brief Returns a local 1D hypothesis used for theEdge + * \brief Returns a propagation hypothesis assigned to theEdge */ - const SMESH_Hypothesis* isLocal1DHypothesis (SMESH_Mesh& theMesh, - const TopoDS_Shape& theEdge) + const SMESH_Hypothesis* getProagationHyp (SMESH_Mesh& theMesh, + const TopoDS_Shape& theEdge) { - static SMESH_HypoFilter hypo ( SMESH_HypoFilter::HasDim( 1 )); - hypo.AndNot( hypo.IsAlgo() ).AndNot( hypo.IsAssignedTo( theMesh.GetMeshDS()->ShapeToMesh() )); - - return theMesh.GetHypothesis( theEdge, hypo, true ); + static SMESH_HypoFilter propagHypFilter + ( SMESH_HypoFilter::HasName( StdMeshers_Propagation::GetName ())); + return theMesh.GetHypothesis( theEdge, propagHypFilter, true ); + } + //================================================================================ + /*! + * \brief Return an iterator on a list of submeshes + */ + SMESH_subMeshIteratorPtr iterate( list::const_iterator from, + list::const_iterator to) + { + typedef SMESH_subMesh* TsubMesh; + typedef SMDS_SetIterator< TsubMesh, list< TsubMesh >::const_iterator > TIterator; + return SMESH_subMeshIteratorPtr ( new TIterator( from, to )); } //================================================================================ /*! @@ -225,126 +236,212 @@ namespace { */ bool buildPropagationChain ( SMESH_subMesh* theMainSubMesh ) { - // const TopoDS_Shape& theMainEdge = theMainSubMesh->GetSubShape(); -// if (theMainEdge.ShapeType() != TopAbs_EDGE) return true; - -// SMESH_Mesh* mesh = theMainSubMesh->GetFather(); - -// EventListenerData* chainData = new PropagationMgrData(HAS_PROPAG_HYP); -// theMainSubMesh->SetEventListener( getListener(), chainData, theMainSubMesh ); - -// // Edges submeshes, on which the 1D hypothesis will be propagated from -// list & chain = chainData->mySubMeshes; - -// // List of edges, added to chain on the previous cycle pass -// TopTools_ListOfShape listPrevEdges; -// listPrevEdges.Append(theMainEdge.Oriented( TopAbs_FORWARD )); - -// // 4____3____2____3____4____5 -// // | | | | | | Number in the each knot of -// // | | | | | | grid indicates cycle pass, -// // 3____2____1____2____3____4 on which corresponding edge -// // | | | | | | (perpendicular to the plane -// // | | | | | | of view) will be found. -// // 2____1____0____1____2____3 -// // | | | | | | -// // | | | | | | -// // 3____2____1____2____3____4 - -// // Collect all edges pass by pass -// while (listPrevEdges.Extent() > 0) { -// // List of edges, added to chain on this cycle pass -// TopTools_ListOfShape listCurEdges; - -// // Find the next portion of edges -// TopTools_ListIteratorOfListOfShape itE (listPrevEdges); -// for (; itE.More(); itE.Next()) { -// TopoDS_Shape anE = itE.Value(); - -// // Iterate on faces, having edge -// TopTools_ListIteratorOfListOfShape itA (mesh->GetAncestors(anE)); -// for (; itA.More(); itA.Next()) { -// TopoDS_Shape aW = itA.Value(); - -// // There are objects of different type among the ancestors of edge -// if (aW.ShapeType() == TopAbs_WIRE) { -// TopoDS_Shape anOppE; - -// BRepTools_WireExplorer aWE (TopoDS::Wire(aW)); -// Standard_Integer nb = 1, found = 0; -// TopTools_Array1OfShape anEdges (1,4); -// for (; aWE.More(); aWE.Next(), nb++) { -// if (nb > 4) { -// found = 0; -// break; -// } -// anEdges(nb) = aWE.Current(); -// if (!_mapAncestors.Contains(anEdges(nb))) { -// MESSAGE("WIRE EXPLORER HAVE GIVEN AN INVALID EDGE !!!"); -// break; -// } -// if (anEdges(nb).IsSame(anE)) found = nb; -// } - -// if (nb == 5 && found > 0) { -// // Quadrangle face found, get an opposite edge -// Standard_Integer opp = ( found + 2 ) % 4; -// anOppE = anEdges(opp); - -// // add anOppE to aChain if ... -// PropagationMgrData* data = getData( *mesh, anOppE ); -// if ( !data || data->State() == WAIT_PROPAG_HYP ) { // ... anOppE is not in any chain -// if ( !isLocal1DHypothesis( *mesh, anOppE )) { // ... no other 1d hyp on anOppE -// // Add found edge to the chain oriented so that to -// // have it co-directed with a forward MainEdge -// TopAbs_Orientation ori = anE.Orientation(); -// if ( anEdges(opp).Orientation() == anEdges(found).Orientation() ) -// ori = TopAbs::Reverse( ori ); -// anOppE.Orientation( ori ); -// aChain.Add(anOppE); -// listCurEdges.Append(anOppE); -// } -// else { -// // Collision! -// MESSAGE("Error: Collision between propagated hypotheses"); -// CleanMeshOnPropagationChain(theMainEdge); -// aChain.Clear(); -// return ( aMainHyp == isLocal1DHypothesis(aMainEdgeForOppEdge) ); -// } -// } -// } -// } // if (nb == 5 && found > 0) -// } // if (aF.ShapeType() == TopAbs_WIRE) -// } // for (; itF.More(); itF.Next()) -// } // for (; itE.More(); itE.Next()) - -// listPrevEdges = listCurEdges; -// } // while (listPrevEdges.Extent() > 0) - -// CleanMeshOnPropagationChain(theMainEdge); + DBGMSG( "buildPropagationChain from " << theMainSubMesh->GetId() ); + const TopoDS_Shape& theMainEdge = theMainSubMesh->GetSubShape(); + if (theMainEdge.ShapeType() != TopAbs_EDGE) return true; + + SMESH_Mesh* mesh = theMainSubMesh->GetFather(); + + PropagationMgrData* chainData = getData( theMainSubMesh ); + chainData->SetState( HAS_PROPAG_HYP ); + + // Edge submeshes, to which the 1D hypothesis will be propagated from theMainEdge + list & chain = chainData->mySubMeshes; + chain.clear(); + chain.push_back( theMainSubMesh ); + + TopTools_MapOfShape checkedShapes; + checkedShapes.Add( theMainEdge ); + + list::iterator smIt = chain.begin(); + for ( ; smIt != chain.end(); ++smIt ) + { + const TopoDS_Edge& anE = TopoDS::Edge( (*smIt)->GetSubShape() ); + PropagationMgrData* data = findData( *smIt ); + if ( !data ) continue; + + // Iterate on faces, having edge + TopTools_ListIteratorOfListOfShape itA (mesh->GetAncestors(anE)); + for (; itA.More(); itA.Next()) + { + // there are objects of different type among the ancestors of edge + if ( itA.Value().ShapeType() != TopAbs_WIRE || !checkedShapes.Add( itA.Value() )) + continue; + + // Get ordered edges and find index of anE in a sequence + BRepTools_WireExplorer aWE (TopoDS::Wire(itA.Value())); + vector edges; + edges.reserve(4); + int edgeIndex = 0; + for (; aWE.More(); aWE.Next()) { + TopoDS_Edge edge = aWE.Current(); + edge.Orientation( aWE.Orientation() ); + if ( edge.IsSame( anE )) + edgeIndex = edges.size(); + edges.push_back( edge ); + } + + // Find an edge opposite to anE + TopoDS_Edge anOppE; + if ( edges.size() < 4 ) { + continue; // too few edges + } + else if ( edges.size() == 4 ) { + int oppIndex = edgeIndex + 2; + if ( oppIndex > 3 ) oppIndex -= 4; + anOppE = edges[ oppIndex ]; + } + else { + // count nb sides + TopoDS_Edge prevEdge = anE; + int nbSide = 0, eIndex = edgeIndex + 1; + for ( int i = 0; i < edges.size(); ++i, ++eIndex ) + { + if ( eIndex == edges.size() ) + eIndex = 0; + if ( !SMESH_Algo::IsContinuous( prevEdge, edges[ eIndex ])) { + nbSide++; + } + else { + // check that anE is not a part of a composite side + if ( anE.IsSame( prevEdge ) || anE.IsSame( edges[ eIndex ])) { + anOppE.Nullify(); break; + } + } + if ( nbSide == 2 ) { // opposite side + if ( !anOppE.IsNull() ) { + // composite opposite side -> stop propagation + anOppE.Nullify(); break; + } + anOppE = edges[ eIndex ]; + } + if ( nbSide == 5 ) { + anOppE.Nullify(); break; // too many sides + } + prevEdge = edges[ eIndex ]; + } + if ( anOppE.IsNull() ) + continue; + if ( nbSide != 4 ) { + DBGMSG( nbSide << " sides in wire #" << mesh->GetMeshDS()->ShapeToIndex( itA.Value() ) << " - SKIP" ); + continue; + } + } + if ( anOppE.IsNull() || !checkedShapes.Add( anOppE )) + continue; + SMESH_subMesh* oppSM = mesh->GetSubMesh( anOppE ); + PropagationMgrData* oppData = getData( oppSM ); + + // Add anOppE to aChain if ... + if ( oppData->State() == WAIT_PROPAG_HYP ) // ... anOppE is not in any chain + { + oppData->SetSource( theMainSubMesh ); + if ( !getLocal1DHyp( *mesh, anOppE )) // ... no 1d hyp on anOppE + { + oppData->myForward = data->myForward; + if ( edges[ edgeIndex ].Orientation() == anOppE.Orientation() ) + oppData->myForward = !oppData->myForward; + chain.push_back( oppSM ); + oppSM->ComputeStateEngine( SMESH_subMesh::CLEAN ); + oppData->SetState( IN_CHAIN ); + DBGMSG( "set IN_CHAIN on " << oppSM->GetId() ); + } + else { + oppData->SetState( LAST_IN_CHAIN ); + DBGMSG( "set LAST_IN_CHAIN on " << oppSM->GetId() ); + } + } + else if ( oppData->State() == LAST_IN_CHAIN ) // anOppE breaks other chain + { + DBGMSG( "encounters LAST_IN_CHAIN on " << oppSM->GetId() ); + oppData->AddSource( theMainSubMesh ); + } + } // loop on face ancestors + } // loop on the chain + + // theMainSubMesh must not be in a chain + chain.pop_front(); + return true; } //================================================================================ /*! * \brief Clear propagation chain */ - //================================================================================ - bool clearPropagationChain( SMESH_subMesh* subMesh ) { - if ( PropagationMgrData* data = getData( subMesh )) { - if ( data->State() == IN_CHAIN ) + DBGMSG( "clearPropagationChain from " << subMesh->GetId() ); + if ( PropagationMgrData* data = findData( subMesh )) + { + switch ( data->State() ) { + case IN_CHAIN: return clearPropagationChain( data->GetSource() ); + + case HAS_PROPAG_HYP: { + SMESH_subMeshIteratorPtr smIt = data->GetChain(); + while ( smIt->more() ) { + SMESH_subMesh* sm = smIt->next(); + getData( sm )->Init(); + sm->ComputeStateEngine( SMESH_subMesh::CLEAN ); + } + data->Init(); + break; + } + case LAST_IN_CHAIN: { + SMESH_subMeshIteratorPtr smIt = iterate( data->mySubMeshes.begin(), + data->mySubMeshes.end()); + while ( smIt->more() ) + clearPropagationChain( smIt->next() ); + data->Init(); + break; + } + default:; + } return true; } return false; - } + } + + + //================================================================================ + /*! + * \brief Return an iterator on chain submeshes + */ + //================================================================================ + + SMESH_subMeshIteratorPtr PropagationMgrData::GetChain() const + { + switch ( State() ) { + case HAS_PROPAG_HYP: + return iterate( mySubMeshes.begin(), mySubMeshes.end() ); + case IN_CHAIN: + if ( mySubMeshes.empty() ) break; + return getData( mySubMeshes.front() )->GetChain(); + default:; + } + return iterate( mySubMeshes.end(), mySubMeshes.end() ); + } + //================================================================================ + /*! + * \brief Return a propagation source submesh + */ + //================================================================================ + + SMESH_subMesh* PropagationMgrData::GetSource() const + { + if ( myType == IN_CHAIN ) + if ( !mySubMeshes.empty() ) + return mySubMeshes.front(); + return 0; + } //================================================================================ /*! * \brief Constructor */ + //================================================================================ + PropagationMgr::PropagationMgr() : SMESH_subMeshEventListener( false ) // won't be deleted by submesh {} @@ -352,14 +449,16 @@ namespace { /*! * \brief Set PropagationMgr on a submesh */ + //================================================================================ + void PropagationMgr::Set(SMESH_subMesh * submesh) { - EventListenerData* data = EventListenerData::MakeData(submesh,WAIT_PROPAG_HYP); - + DBGMSG( "PropagationMgr::Set() on " << submesh->GetId() ); + EventListenerData* data = new PropagationMgrData(); submesh->SetEventListener( getListener(), data, submesh ); const SMESH_Hypothesis * propagHyp = - submesh->GetFather()->GetHypothesis( submesh->GetSubShape(), propagHypFilter(), true ); + getProagationHyp( *submesh->GetFather(), submesh->GetSubShape() ); if ( propagHyp ) getListener()->ProcessEvent( SMESH_subMesh::ADD_HYP, SMESH_subMesh::ALGO_EVENT, @@ -367,7 +466,28 @@ namespace { data, propagHyp); } + //================================================================================ + /*! + * \brief Return an edge from which hypotheses are propagated + */ + //================================================================================ + TopoDS_Edge PropagationMgr::GetSource(SMESH_subMesh * submesh) + { + if ( PropagationMgrData* data = findData( submesh )) { + if ( data->State() == IN_CHAIN ) { + if ( SMESH_subMesh* sm = data->GetSource() ) + { + TopoDS_Shape edge = sm->GetSubShape(); + edge = edge.Oriented( data->myForward ? TopAbs_FORWARD : TopAbs_REVERSED ); + DBGMSG( " GetSource() = edge " << sm->GetId() << " REV = " << (!data->myForward)); + if ( edge.ShapeType() == TopAbs_EDGE ) + return TopoDS::Edge( edge ); + } + } + } + return TopoDS_Edge(); + } //================================================================================ /*! * \brief React on events on 1D submeshes @@ -377,31 +497,36 @@ namespace { void PropagationMgr::ProcessEvent(const int event, const int eventType, SMESH_subMesh* subMesh, - SMESH_subMeshEventListenerData* data, + SMESH_subMeshEventListenerData* listenerData, const SMESH_Hypothesis* hyp) { - if ( !data ) + if ( !listenerData ) return; if ( !hyp || hyp->GetType() != SMESHDS_Hypothesis::PARAM_ALGO || hyp->GetDim() != 1 ) return; if ( eventType != SMESH_subMesh::ALGO_EVENT ) return; + DBGMSG( "PropagationMgr::ProcessEvent() on " << subMesh->GetId() ); - bool isPropagHyp = ( StdMeshers_Propagation::GetName() != hyp->GetName() ); + bool isPropagHyp = ( StdMeshers_Propagation::GetName() == hyp->GetName() ); - switch ( data->myType ) { + PropagationMgrData* data = static_cast( listenerData ); + switch ( data->State() ) { - case WAIT_PROPAG_HYP: { // no propagation hyp in chain + case WAIT_PROPAG_HYP: { // propagation hyp or local 1D hyp is missing // -------------------------------------------------------- - if ( !isPropagHyp ) + bool hasPropagHyp = ( isPropagHyp || + getProagationHyp( *subMesh->GetFather(), subMesh->GetSubShape()) ); + if ( !hasPropagHyp ) return; - if ( !isLocal1DHypothesis( *subMesh->GetFather(), subMesh->GetSubShape())) + bool hasLocal1DHyp = getLocal1DHyp( *subMesh->GetFather(), subMesh->GetSubShape()); + if ( !hasLocal1DHyp ) return; if ( event == SMESH_subMesh::ADD_HYP || - event == SMESH_subMesh::ADD_FATHER_HYP ) // add propagation hyp + event == SMESH_subMesh::ADD_FATHER_HYP ) // add local or propagation hyp { + DBGMSG( "ADD_HYP propagation to WAIT_PROPAG_HYP " << subMesh->GetId() ); // build propagation chain - clearPropagationChain( subMesh ); buildPropagationChain( subMesh ); } return; @@ -411,32 +536,57 @@ namespace { switch ( event ) { case SMESH_subMesh::REMOVE_HYP: case SMESH_subMesh::REMOVE_FATHER_HYP: // remove propagation hyp - if ( isPropagHyp ) + if ( isPropagHyp && !getProagationHyp( *subMesh->GetFather(), subMesh->GetSubShape()) ) { + DBGMSG( "REMOVE_HYP propagation from HAS_PROPAG_HYP " << subMesh->GetId() ); // clear propagation chain + clearPropagationChain( subMesh ); } return; case SMESH_subMesh::MODIF_HYP: // hyp modif // clear mesh in a chain + DBGMSG( "MODIF_HYP on HAS_PROPAG_HYP " << subMesh->GetId() ); + SMESH_subMeshIteratorPtr smIt = data->GetChain(); + while ( smIt->more() ) { + SMESH_subMesh* smInChain = smIt->next(); + smInChain->AlgoStateEngine( SMESH_subMesh::MODIF_HYP, + (SMESH_Hypothesis*) hyp ); + } return; } return; } case IN_CHAIN: { // submesh is in propagation chain // -------------------------------------------------------- - if ( event == SMESH_subMesh::ADD_HYP ) // add local hypothesis - if ( isPropagHyp ) - ; // collision - else - ; // rebuild propagation chain - return; + if ( event == SMESH_subMesh::ADD_HYP ) { // add local hypothesis + if ( isPropagHyp ) { // propagation hyp added + DBGMSG( "ADD_HYP propagation on IN_CHAIN " << subMesh->GetId() ); + // collision - do nothing + } + else { // 1D hyp added + // rebuild propagation chain + DBGMSG( "ADD_HYP 1D on IN_CHAIN " << subMesh->GetId() ); + SMESH_subMesh* sourceSM = data->GetSource(); + clearPropagationChain( sourceSM ); + buildPropagationChain( sourceSM ); + } + } + return; } case LAST_IN_CHAIN: { // submesh with local 1D hyp, breaking a chain // -------------------------------------------------------- - if ( event == SMESH_subMesh::REMOVE_HYP ) // remove local hyp - ; // rebuild propagation chain + if ( event == SMESH_subMesh::REMOVE_HYP ) { // remove local hyp + // rebuild propagation chain + DBGMSG( "REMOVE_HYP 1D from LAST_IN_CHAIN " << subMesh->GetId() ); + list sourceSM = data->mySubMeshes; + clearPropagationChain( subMesh ); + SMESH_subMeshIteratorPtr smIt = iterate( sourceSM.begin(), sourceSM.end()); + while ( smIt->more() ) + buildPropagationChain( smIt->next() ); + } return; } } // switch by SubMeshState } + } // namespace diff --git a/src/StdMeshers/StdMeshers_Propagation.hxx b/src/StdMeshers/StdMeshers_Propagation.hxx index c0d2f3cdf..62ad2a439 100644 --- a/src/StdMeshers/StdMeshers_Propagation.hxx +++ b/src/StdMeshers/StdMeshers_Propagation.hxx @@ -64,7 +64,7 @@ class STDMESHERS_EXPORT StdMeshers_Propagation:public SMESH_Hypothesis static void SetPropagationMgr(SMESH_subMesh* subMesh); /*! - * \brief Return an edge from which hypotheses are propagated from + * \brief Return an edge from which hypotheses are propagated * \param theMesh - mesh * \param theEdge - edge to which hypotheses are propagated * \retval TopoDS_Edge - source edge, also passing orientation diff --git a/src/StdMeshers/StdMeshers_QuadranglePreference.cxx b/src/StdMeshers/StdMeshers_QuadranglePreference.cxx index b16eeb58e..3e04aa872 100644 --- a/src/StdMeshers/StdMeshers_QuadranglePreference.cxx +++ b/src/StdMeshers/StdMeshers_QuadranglePreference.cxx @@ -42,7 +42,7 @@ StdMeshers_QuadranglePreference::StdMeshers_QuadranglePreference(int hyp :SMESH_Hypothesis(hypId, studyId, gen) { _name = "QuadranglePreference"; - _param_algo_dim = 2; // is used by StdMeshers_Quadrangle_2D + _param_algo_dim = -2; // auxiliary used by StdMeshers_Quadrangle_2D } //============================================================================= diff --git a/src/StdMeshers/StdMeshers_Quadrangle_2D.cxx b/src/StdMeshers/StdMeshers_Quadrangle_2D.cxx index 8a1659402..2c3c74128 100644 --- a/src/StdMeshers/StdMeshers_Quadrangle_2D.cxx +++ b/src/StdMeshers/StdMeshers_Quadrangle_2D.cxx @@ -119,7 +119,7 @@ bool StdMeshers_Quadrangle_2D::CheckHypothesis aStatus = SMESH_Hypothesis::HYP_OK; // there is only one compatible Hypothesis so far - const list &hyps = GetUsedHypothesis(aMesh, aShape); + const list &hyps = GetUsedHypothesis(aMesh, aShape, false); myQuadranglePreference = hyps.size() > 0; return isOk; @@ -132,9 +132,10 @@ bool StdMeshers_Quadrangle_2D::CheckHypothesis //============================================================================= bool StdMeshers_Quadrangle_2D::Compute (SMESH_Mesh& aMesh, - const TopoDS_Shape& aShape) throw (SALOME_Exception) + const TopoDS_Shape& aShape)// throw (SALOME_Exception) { - Unexpect aCatch(SalomeException); + // PAL14921. Enable catching std::bad_alloc and Standard_OutOfMemory outside + //Unexpect aCatchSalomeException); SMESHDS_Mesh * meshDS = aMesh.GetMeshDS(); aMesh.GetSubMesh(aShape); @@ -238,6 +239,9 @@ bool StdMeshers_Quadrangle_2D::Compute (SMESH_Mesh& aMesh, const vector& uv_e2 = quad->side[2]->GetUVPtStruct(true,1 ); const vector& uv_e3 = quad->side[3]->GetUVPtStruct(false,0); + if ( uv_e0.empty() || uv_e1.empty() || uv_e2.empty() || uv_e3.empty() ) + return error( COMPERR_BAD_INPUT_MESH ); + double eps = Precision::Confusion(); // Boundary quadrangles @@ -562,10 +566,8 @@ bool StdMeshers_Quadrangle_2D::Compute (SMESH_Mesh& aMesh, FaceQuadStruct* StdMeshers_Quadrangle_2D::CheckNbEdges(SMESH_Mesh & aMesh, const TopoDS_Shape & aShape) - throw(SALOME_Exception) + //throw(SALOME_Exception) { - Unexpect aCatch(SalomeException); - const TopoDS_Face & F = TopoDS::Face(aShape); const bool ignoreMediumNodes = _quadraticMesh; @@ -596,16 +598,14 @@ FaceQuadStruct* StdMeshers_Quadrangle_2D::CheckNbEdges(SMESH_Mesh & aMes sideEdges.splice( sideEdges.end(), edges, edges.begin()); // edges.front() -> sideEdges.end() bool sameSide = true; while ( !edges.empty() && sameSide ) { - GeomAbs_Shape cont = SMESH_Algo::Continuity( sideEdges.back(), edges.front() ); - sameSide = ( cont >= GeomAbs_G1 ); + sameSide = SMESH_Algo::IsContinuous( sideEdges.back(), edges.front() ); if ( sameSide ) sideEdges.splice( sideEdges.end(), edges, edges.begin()); } if ( nbSides == 0 ) { // go backward from the first edge sameSide = true; while ( !edges.empty() && sameSide ) { - GeomAbs_Shape cont = SMESH_Algo::Continuity( sideEdges.front(), edges.back() ); - sameSide = ( cont >= GeomAbs_G1 ); + sameSide = SMESH_Algo::IsContinuous( sideEdges.front(), edges.back() ); if ( sameSide ) sideEdges.splice( sideEdges.begin(), edges, --edges.end()); } @@ -645,10 +645,8 @@ FaceQuadStruct* StdMeshers_Quadrangle_2D::CheckNbEdges(SMESH_Mesh & aMes FaceQuadStruct *StdMeshers_Quadrangle_2D::CheckAnd2Dcompute (SMESH_Mesh & aMesh, const TopoDS_Shape & aShape, - const bool CreateQuadratic) throw(SALOME_Exception) + const bool CreateQuadratic) //throw(SALOME_Exception) { - Unexpect aCatch(SalomeException); - _quadraticMesh = CreateQuadratic; FaceQuadStruct *quad = CheckNbEdges(aMesh, aShape); @@ -656,7 +654,12 @@ FaceQuadStruct *StdMeshers_Quadrangle_2D::CheckAnd2Dcompute if(!quad) return 0; // set normalized grid on unit square in parametric domain - SetNormalizedGrid(aMesh, aShape, quad); + bool stat = SetNormalizedGrid(aMesh, aShape, quad); + if(!stat) { + if(!quad) + delete quad; + quad = 0; + } return quad; } @@ -695,9 +698,8 @@ namespace { bool StdMeshers_Quadrangle_2D::SetNormalizedGrid (SMESH_Mesh & aMesh, const TopoDS_Shape& aShape, - FaceQuadStruct* & quad) throw (SALOME_Exception) + FaceQuadStruct* & quad) //throw (SALOME_Exception) { - Unexpect aCatch(SalomeException); // Algorithme décrit dans "Génération automatique de maillages" // P.L. GEORGE, MASSON, § 6.4.1 p. 84-85 // traitement dans le domaine paramétrique 2d u,v @@ -738,7 +740,8 @@ bool StdMeshers_Quadrangle_2D::SetNormalizedGrid (SMESH_Mesh & aMesh, const vector& uv_e3 = GetUVPtStructIn( quad, 3, nbvertic - 1 ); if ( uv_e0.empty() || uv_e1.empty() || uv_e2.empty() || uv_e3.empty() ) - return error(dfltErr(), "Can't find nodes on sides"); + //return error( "Can't find nodes on sides"); + return error( COMPERR_BAD_INPUT_MESH ); // nodes Id on "in" edges if (! quad->isEdgeOut[0]) { @@ -888,14 +891,11 @@ static gp_UV CalcUV(double x0, double x1, double y0, double y1, bool StdMeshers_Quadrangle_2D::ComputeQuadPref (SMESH_Mesh & aMesh, const TopoDS_Shape& aShape, FaceQuadStruct* quad) - throw (SALOME_Exception) { - Unexpect aCatch(SalomeException); - SMESHDS_Mesh * meshDS = aMesh.GetMeshDS(); const TopoDS_Face& F = TopoDS::Face(aShape); Handle(Geom_Surface) S = BRep_Tool::Surface(F); - const TopoDS_Wire& W = BRepTools::OuterWire(F); +// const TopoDS_Wire& W = BRepTools::OuterWire(F); bool WisF = true; // if(W.Orientation()==TopAbs_FORWARD) // WisF = true; diff --git a/src/StdMeshers/StdMeshers_Quadrangle_2D.hxx b/src/StdMeshers/StdMeshers_Quadrangle_2D.hxx index 90db88e55..72b317be2 100644 --- a/src/StdMeshers/StdMeshers_Quadrangle_2D.hxx +++ b/src/StdMeshers/StdMeshers_Quadrangle_2D.hxx @@ -47,14 +47,8 @@ enum TSideID { BOTTOM_SIDE=0, RIGHT_SIDE, TOP_SIDE, LEFT_SIDE, NB_SIDES }; typedef uvPtStruct UVPtStruct; typedef struct faceQuadStruct { - //int nbPts[4]; - //TopoDS_Edge edge[4]; vector< StdMeshers_FaceSide*> side; - //double first[4]; - //double last[4]; - //bool isEdgeForward[4]; bool isEdgeOut[4]; // true, if an edge has more nodes, than the opposite - //UVPtStruct* uv_edges[4]; UVPtStruct* uv_grid; ~faceQuadStruct(); } FaceQuadStruct; @@ -70,32 +64,27 @@ public: SMESH_Hypothesis::Hypothesis_Status& aStatus); virtual bool Compute(SMESH_Mesh& aMesh, - const TopoDS_Shape& aShape) - throw (SALOME_Exception); + const TopoDS_Shape& aShape); FaceQuadStruct* CheckAnd2Dcompute(SMESH_Mesh& aMesh, const TopoDS_Shape& aShape, - const bool CreateQuadratic) - throw (SALOME_Exception); + const bool CreateQuadratic); protected: FaceQuadStruct* CheckNbEdges(SMESH_Mesh& aMesh, - const TopoDS_Shape& aShape) - throw (SALOME_Exception); + const TopoDS_Shape& aShape); bool SetNormalizedGrid(SMESH_Mesh& aMesh, const TopoDS_Shape& aShape, - FaceQuadStruct*& quad) - throw (SALOME_Exception); + FaceQuadStruct*& quad); /** * Special function for creation only quandrangle faces */ bool ComputeQuadPref(SMESH_Mesh& aMesh, const TopoDS_Shape& aShape, - FaceQuadStruct* quad) - throw (SALOME_Exception); + FaceQuadStruct* quad); UVPtStruct* LoadEdgePoints2(SMESH_Mesh& aMesh, const TopoDS_Face& F, const TopoDS_Edge& E, diff --git a/src/StdMeshers/StdMeshers_RadialPrism_3D.cxx b/src/StdMeshers/StdMeshers_RadialPrism_3D.cxx index c83bff525..128b32077 100644 --- a/src/StdMeshers/StdMeshers_RadialPrism_3D.cxx +++ b/src/StdMeshers/StdMeshers_RadialPrism_3D.cxx @@ -98,13 +98,14 @@ bool StdMeshers_RadialPrism_3D::CheckHypothesis(SMESH_Mesh& SMESH_Hypothesis::Hypothesis_Status& aStatus) { // check aShape that must have 2 shells +/* PAL16229 if ( TAssocTool::Count( aShape, TopAbs_SOLID, 0 ) != 1 || TAssocTool::Count( aShape, TopAbs_SHELL, 0 ) != 2 ) { aStatus = HYP_BAD_GEOMETRY; return false; } - +*/ myNbLayerHypo = 0; myDistributionHypo = 0; @@ -167,7 +168,7 @@ bool StdMeshers_RadialPrism_3D::Compute(SMESH_Mesh& aMesh, const TopoDS_Shape& a if ( !outerShell.IsSame( It.Value() )) innerShell = It.Value(); if ( nbShells != 2 ) - return error(COMPERR_BAD_SHAPE, SMESH_Comment("Must be 2 shells but not")<ShapeToIndex( outFace )); } else { inFace = TopoDS::Face( shape2ShapeMap( outFace )); @@ -222,12 +223,18 @@ bool StdMeshers_RadialPrism_3D::Compute(SMESH_Mesh& aMesh, const TopoDS_Shape& a vector< const TNodeColumn* > columns( nbNodes ); for ( int i = 0; i < nbNodes; ++i ) { - const SMDS_MeshNode* n = face->GetNode( i ); - TNode2ColumnMap::iterator n_col = node2columnMap.find( n ); - if ( n_col != node2columnMap.end() ) + const SMDS_MeshNode* nIn = face->GetNode( i ); + TNode2ColumnMap::iterator n_col = node2columnMap.find( nIn ); + if ( n_col != node2columnMap.end() ) { columns[ i ] = & n_col->second; - else - columns[ i ] = makeNodeColumn( node2columnMap, n, nodeIn2OutMap[ n ] ); + } + else { + TNodeNodeMap::iterator nInOut = nodeIn2OutMap.find( nIn ); + if ( nInOut == nodeIn2OutMap.end() ) + RETURN_BAD_RESULT("No matching node for "<< nIn->GetID() << + " in face "<< face->GetID()); + columns[ i ] = makeNodeColumn( node2columnMap, nIn, nInOut->second ); + } } StdMeshers_Prism_3D::AddPrisms( columns, myHelper ); @@ -312,24 +319,24 @@ public: const StdMeshers_LayerDistribution* hyp) { double len = pIn.Distance( pOut ); - if ( len <= DBL_MIN ) return error(dfltErr(),"Too close points of inner and outer shells"); + if ( len <= DBL_MIN ) return error("Too close points of inner and outer shells"); if ( !hyp || !hyp->GetLayerDistribution() ) - return error(dfltErr(), "Invalid LayerDistribution hypothesis"); + return error( "Invalid LayerDistribution hypothesis"); myUsedHyps.clear(); myUsedHyps.push_back( hyp->GetLayerDistribution() ); TopoDS_Edge edge = BRepBuilderAPI_MakeEdge( pIn, pOut ); SMESH_Hypothesis::Hypothesis_Status aStatus; if ( !StdMeshers_Regular_1D::CheckHypothesis( aMesh, edge, aStatus )) - return error(dfltErr(), "StdMeshers_Regular_1D::CheckHypothesis() failed" - "with LayerDistribution hypothesis"); + return error( "StdMeshers_Regular_1D::CheckHypothesis() failed " + "with LayerDistribution hypothesis"); BRepAdaptor_Curve C3D(edge); double f = C3D.FirstParameter(), l = C3D.LastParameter(); list< double > params; if ( !StdMeshers_Regular_1D::computeInternalParameters( C3D, len, f, l, params, false )) - return error(dfltErr(),"StdMeshers_Regular_1D failed to compute layers distribution"); + return error("StdMeshers_Regular_1D failed to compute layers distribution"); positions.clear(); positions.reserve( params.size() ); diff --git a/src/StdMeshers/StdMeshers_Regular_1D.cxx b/src/StdMeshers/StdMeshers_Regular_1D.cxx index 9e59aa0c6..ba5f74503 100644 --- a/src/StdMeshers/StdMeshers_Regular_1D.cxx +++ b/src/StdMeshers/StdMeshers_Regular_1D.cxx @@ -37,6 +37,7 @@ #include "StdMeshers_Deflection1D.hxx" #include "StdMeshers_AutomaticLength.hxx" #include "StdMeshers_SegmentLengthAroundVertex.hxx" +#include "StdMeshers_Propagation.hxx" #include "SMESH_Gen.hxx" #include "SMESH_Mesh.hxx" @@ -85,6 +86,7 @@ StdMeshers_Regular_1D::StdMeshers_Regular_1D(int hypId, int studyId, _compatibleHypothesis.push_back("AutomaticLength"); _compatibleHypothesis.push_back("QuadraticMesh"); // auxiliary !!! + _compatibleHypothesis.push_back("Propagation"); // auxiliary !!! } //============================================================================= @@ -410,6 +412,7 @@ void StdMeshers_Regular_1D::SetEventListener(SMESH_subMesh* subMesh) // while (smIt->more()) { // subMesh->SetEventListener( &listener, 0, smIt->next() ); // } + StdMeshers_Propagation::SetPropagationMgr( subMesh ); } //============================================================================= @@ -627,7 +630,7 @@ bool StdMeshers_Regular_1D::computeInternalParameters(Adaptor3d_Curve& theC3d, } GCPnts_UniformAbscissa Discret(theC3d, eltSize, f, l); if ( !Discret.IsDone() ) - return error( dfltErr(), "GCPnts_UniformAbscissa failed"); + return error( "GCPnts_UniformAbscissa failed"); int NbPoints = Discret.NbPoints(); for ( int i = 2; i < NbPoints; i++ ) @@ -759,7 +762,7 @@ bool StdMeshers_Regular_1D::Compute(SMESH_Mesh & aMesh, const TopoDS_Shape & aSh list< double > params; bool reversed = false; if ( !_mainEdge.IsNull() ) - reversed = aMesh.IsReversedInChain( EE, _mainEdge ); + reversed = ( _mainEdge.Orientation() == TopAbs_REVERSED ); BRepAdaptor_Curve C3d( E ); double length = EdgeLength( E ); @@ -774,6 +777,11 @@ bool StdMeshers_Regular_1D::Compute(SMESH_Mesh & aMesh, const TopoDS_Shape & aSh const SMDS_MeshNode * idPrev = idFirst; double parPrev = f; double parLast = l; + if(reversed) { + idPrev = idLast; + parPrev = l; + parLast = f; + } for (list::iterator itU = params.begin(); itU != params.end(); itU++) { double param = *itU; @@ -809,16 +817,24 @@ bool StdMeshers_Regular_1D::Compute(SMESH_Mesh & aMesh, const TopoDS_Shape & aSh meshDS->SetMeshElementOnShape(edge, shapeID); } else { - SMDS_MeshEdge* edge = meshDS->AddEdge(idPrev, idLast); - meshDS->SetMeshElementOnShape(edge, shapeID); + if(!reversed) { + SMDS_MeshEdge* edge = meshDS->AddEdge(idPrev, idLast); + meshDS->SetMeshElementOnShape(edge, shapeID); + } + else { + SMDS_MeshEdge* edge = meshDS->AddEdge(idPrev, idFirst); + meshDS->SetMeshElementOnShape(edge, shapeID); + } } } - else { + else + { + //MESSAGE("************* Degenerated edge! *****************"); + // Edge is a degenerated Edge : We put n = 5 points on the edge. const int NbPoints = 5; BRep_Tool::Range( E, f, l ); // PAL15185 double du = (l - f) / (NbPoints - 1); - //MESSAGE("************* Degenerated edge! *****************"); gp_Pnt P = BRep_Tool::Pnt(VFirst); @@ -879,11 +895,11 @@ StdMeshers_Regular_1D::GetUsedHypothesis(SMESH_Mesh & aMesh, // get non-auxiliary assigned to aShape int nbHyp = aMesh.GetHypotheses( aShape, compatibleFilter, _usedHypList, false ); - if (nbHyp == 0) + if (nbHyp == 0 && aShape.ShapeType() == TopAbs_EDGE) { // Check, if propagated from some other edge - if (aShape.ShapeType() == TopAbs_EDGE && - aMesh.IsPropagatedHypothesis(aShape, _mainEdge)) + _mainEdge = StdMeshers_Propagation::GetPropagationSource( aMesh, aShape ); + if ( !_mainEdge.IsNull() ) { // Propagation of 1D hypothesis from on this edge; // get non-auxiliary assigned to _mainEdge diff --git a/src/StdMeshersGUI/StdMeshersGUI_LayerDistributionParamWdg.cxx b/src/StdMeshersGUI/StdMeshersGUI_LayerDistributionParamWdg.cxx index 7537e621b..ed77aaf61 100644 --- a/src/StdMeshersGUI/StdMeshersGUI_LayerDistributionParamWdg.cxx +++ b/src/StdMeshersGUI/StdMeshersGUI_LayerDistributionParamWdg.cxx @@ -48,9 +48,11 @@ */ //================================================================================ -StdMeshersGUI_LayerDistributionParamWdg::StdMeshersGUI_LayerDistributionParamWdg -( SMESH::SMESH_Hypothesis_ptr hyp, - QDialog* dlg ): QHGroupBox(), myDlg( dlg ) +StdMeshersGUI_LayerDistributionParamWdg +::StdMeshersGUI_LayerDistributionParamWdg(SMESH::SMESH_Hypothesis_ptr hyp, + const QString& theName, + QDialog* dlg): + QHGroupBox(), myName(theName), myDlg( dlg ) { init(); set( hyp ); @@ -204,7 +206,7 @@ void StdMeshersGUI_LayerDistributionParamWdg::onEdit() try { QWidget* parent = this; if ( myDlg ) parent = myDlg->parentWidget(); - editor->edit( myHyp, parent ); + editor->edit( myHyp, myName, parent ); } catch(...) { } diff --git a/src/StdMeshersGUI/StdMeshersGUI_LayerDistributionParamWdg.h b/src/StdMeshersGUI/StdMeshersGUI_LayerDistributionParamWdg.h index cc8d7d801..6c6d5f680 100644 --- a/src/StdMeshersGUI/StdMeshersGUI_LayerDistributionParamWdg.h +++ b/src/StdMeshersGUI/StdMeshersGUI_LayerDistributionParamWdg.h @@ -50,7 +50,8 @@ class STDMESHERSGUI_EXPORT StdMeshersGUI_LayerDistributionParamWdg : public QHGr public: StdMeshersGUI_LayerDistributionParamWdg(SMESH::SMESH_Hypothesis_ptr hyp, - QDialog* dlg); + const QString& theName, + QDialog* dlg); ~StdMeshersGUI_LayerDistributionParamWdg(); SMESH::SMESH_Hypothesis_var GetHypothesis() { return myHyp; } @@ -76,6 +77,7 @@ private: QPushButton* myEditButton; QPopupMenu* myHypTypePopup; QDialog* myDlg; + QString myName; QString myParamValue; QStringList myHypTypes; diff --git a/src/StdMeshersGUI/StdMeshersGUI_NbSegmentsCreator.cxx b/src/StdMeshersGUI/StdMeshersGUI_NbSegmentsCreator.cxx index 02bb83a35..f5468b118 100644 --- a/src/StdMeshersGUI/StdMeshersGUI_NbSegmentsCreator.cxx +++ b/src/StdMeshersGUI/StdMeshersGUI_NbSegmentsCreator.cxx @@ -251,8 +251,7 @@ bool StdMeshersGUI_NbSegmentsCreator::readParamsFromHypo( NbSegmentsHypothesisDa StdMeshers::StdMeshers_NumberOfSegments_var h = StdMeshers::StdMeshers_NumberOfSegments::_narrow( initParamsHypothesis() ); - HypothesisData* data = SMESH::GetHypothesisData( hypType() ); - h_data.myName = isCreation() && data ? data->Label : ""; + h_data.myName = hypName(); h_data.myNbSeg = (int) h->GetNumberOfSegments(); int distr = (int) h->GetDistrType(); diff --git a/src/StdMeshersGUI/StdMeshersGUI_StdHypothesisCreator.cxx b/src/StdMeshersGUI/StdMeshersGUI_StdHypothesisCreator.cxx index 1be50e5d1..cfa700236 100644 --- a/src/StdMeshersGUI/StdMeshersGUI_StdHypothesisCreator.cxx +++ b/src/StdMeshersGUI/StdMeshersGUI_StdHypothesisCreator.cxx @@ -512,7 +512,7 @@ bool StdMeshersGUI_StdHypothesisCreator::stdParams( ListOfStdParams& p ) const { HypothesisData* data = SMESH::GetHypothesisData( hypType() ); item.myName = tr( "SMESH_NAME" ); - item.myValue = data ? data->Label : QString(); + item.myValue = data ? hypName() : QString(); p.append( item ); customWidgets()->append(0); } @@ -615,7 +615,7 @@ bool StdMeshersGUI_StdHypothesisCreator::stdParams( ListOfStdParams& p ) const item.myName = tr( "SMESH_LAYERS_DISTRIBUTION" ); p.append( item ); customWidgets()->append - ( new StdMeshersGUI_LayerDistributionParamWdg( h->GetLayerDistribution(), dlg())); + ( new StdMeshersGUI_LayerDistributionParamWdg( h->GetLayerDistribution(), hypName(), dlg())); } else if( hypType()=="ProjectionSource1D" ) {