]> SALOME platform Git repositories - modules/smesh.git/commitdiff
Salome HOME
Join modifications from V3_2_0_maintainance (V3_2_6pre4 - T32x_16Aug2007_16h00m)
authorjfa <jfa@opencascade.com>
Tue, 21 Aug 2007 08:30:33 +0000 (08:30 +0000)
committerjfa <jfa@opencascade.com>
Tue, 21 Aug 2007 08:30:33 +0000 (08:30 +0000)
82 files changed:
adm_local/unix/config_files/check_SMESH.m4
build_configure
configure.ac
idl/SMESH_Gen.idl
resources/StdMeshers.xml
resources/mesh_tree_mesh_partial.png
src/DriverMED/DriverMED_R_SMESHDS_Mesh.cxx
src/DriverUNV/UNV2417_Structure.cxx
src/Makefile.am
src/SMDS/SMDS_Mesh.cxx
src/SMDS/SMDS_Mesh.hxx
src/SMDS/SMESH_SMDS.hxx
src/SMESH/SMESH_Algo.hxx
src/SMESH/SMESH_Block.cxx
src/SMESH/SMESH_Block.hxx
src/SMESH/SMESH_Gen.cxx
src/SMESH/SMESH_HypoFilter.hxx
src/SMESH/SMESH_Mesh.cxx
src/SMESH/SMESH_Mesh.hxx
src/SMESH/SMESH_MeshEditor.cxx
src/SMESH/SMESH_MesherHelper.cxx
src/SMESH/SMESH_MesherHelper.hxx
src/SMESH/SMESH_Pattern.cxx
src/SMESH/SMESH_Pattern.hxx
src/SMESH/SMESH_subMesh.cxx
src/SMESHDS/SMESHDS_SubMesh.hxx
src/SMESHDS/SMESH_SMESHDS.hxx
src/SMESHGUI/SMESHGUI.cxx
src/SMESHGUI/SMESHGUI_ComputeDlg.cxx
src/SMESHGUI/SMESHGUI_ComputeDlg.h
src/SMESHGUI/SMESHGUI_FilterDlg.cxx
src/SMESHGUI/SMESHGUI_Hypotheses.cxx
src/SMESHGUI/SMESHGUI_Hypotheses.h
src/SMESHGUI/SMESHGUI_HypothesesUtils.cxx
src/SMESHGUI/SMESHGUI_MakeNodeAtPointDlg.cxx
src/SMESHGUI/SMESHGUI_MeshOp.cxx
src/SMESHGUI/SMESHGUI_MeshOp.h
src/SMESHGUI/SMESHGUI_MoveNodesDlg.cxx
src/SMESHGUI/SMESHGUI_NodesDlg.cxx
src/SMESHGUI/SMESHGUI_SpinBox.h
src/SMESHGUI/SMESHGUI_TranslationDlg.cxx
src/SMESHGUI/SMESH_msg_en.po
src/SMESH_I/SMESH_2smeshpy.cxx
src/SMESH_I/SMESH_2smeshpy.hxx
src/SMESH_I/SMESH_Filter_i.cxx
src/SMESH_I/SMESH_Gen_i.cxx
src/SMESH_I/SMESH_Gen_i_1.cxx
src/SMESH_I/SMESH_Mesh_i.cxx
src/SMESH_I/SMESH_Mesh_i.hxx
src/SMESH_I/SMESH_Pattern_i.cxx
src/SMESH_I/SMESH_PythonDump.hxx
src/SMESH_I/SMESH_subMesh_i.cxx
src/SMESH_I/SMESH_subMesh_i.hxx
src/SMESH_SWIG/Makefile.am
src/SMESH_SWIG/libSMESH_Swig.i [deleted file]
src/SMESH_SWIG/smeshDC.py
src/SMESH_SWIG_WITHIHM/Makefile.am [new file with mode: 0644]
src/SMESH_SWIG_WITHIHM/libSMESH_Swig.i [new file with mode: 0644]
src/StdMeshers/StdMeshers_CompositeSegment_1D.cxx
src/StdMeshers/StdMeshers_FaceSide.cxx
src/StdMeshers/StdMeshers_FaceSide.hxx
src/StdMeshers/StdMeshers_Hexa_3D.cxx
src/StdMeshers/StdMeshers_Hexa_3D.hxx
src/StdMeshers/StdMeshers_MEFISTO_2D.cxx
src/StdMeshers/StdMeshers_Prism_3D.cxx
src/StdMeshers/StdMeshers_Prism_3D.hxx
src/StdMeshers/StdMeshers_ProjectionUtils.cxx
src/StdMeshers/StdMeshers_ProjectionUtils.hxx
src/StdMeshers/StdMeshers_Projection_1D.cxx
src/StdMeshers/StdMeshers_Projection_2D.cxx
src/StdMeshers/StdMeshers_Projection_3D.cxx
src/StdMeshers/StdMeshers_Propagation.cxx
src/StdMeshers/StdMeshers_Propagation.hxx
src/StdMeshers/StdMeshers_QuadranglePreference.cxx
src/StdMeshers/StdMeshers_Quadrangle_2D.cxx
src/StdMeshers/StdMeshers_Quadrangle_2D.hxx
src/StdMeshers/StdMeshers_RadialPrism_3D.cxx
src/StdMeshers/StdMeshers_Regular_1D.cxx
src/StdMeshersGUI/StdMeshersGUI_LayerDistributionParamWdg.cxx
src/StdMeshersGUI/StdMeshersGUI_LayerDistributionParamWdg.h
src/StdMeshersGUI/StdMeshersGUI_NbSegmentsCreator.cxx
src/StdMeshersGUI/StdMeshersGUI_StdHypothesisCreator.cxx

index f1dbf22f10c840ceb53871457dd415d2429bf674..5518cfa24e8dc98c020cecf2f234e14d781686f0 100644 (file)
@@ -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})
 
index 7f3e6a42e1243a6093deffadecfe6d3b606db79e..66f991e577ff9029fdead56e19f63cec9b04581c 100755 (executable)
@@ -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,
index b2799afe11365831a172c2881c8f82af19517a47..c267da8db1a337a677bd85e8383344306f7bd6dd 100644 (file)
@@ -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 \
index ba4d798d6062283fd4eb0ca7f4885920ca3bc6cb..4f81e6e513ef6dcb71998fda1b17d206ec10d103 100644 (file)
@@ -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 );
 
index 9b1a1dfaf18c2af0b28cc3aa2a8d174072986b13..70530de017ca2665b9b6cd83bb8bec3a48034ffc 100644 (file)
@@ -60,6 +60,7 @@
     <hypothesis type="QuadranglePreference"
                 label-id="Quadrangle Preference"
                 icon-id="mesh_algo_quad.png"
+                auxiliary="true"
                 dim="2"/>
 
     <hypothesis type="QuadraticMesh"
index 2ab75b32ddd6097d1fc068cc27f320efd253cd9b..2d7f09ca991c1bb957dc03238a61f6c53f0e5b13 100755 (executable)
Binary files a/resources/mesh_tree_mesh_partial.png and b/resources/mesh_tree_mesh_partial.png differ
index f87bd3f075bdb6ea0fd6bc2ae5d39ba2809ed5a7..7271a5c86d3f575c190acb73c40ae89a20e54453 100644 (file)
@@ -182,9 +182,9 @@ DriverMED_R_SMESHDS_Mesh
          for(; aGeom2SizeIter != aGeom2Size.end(); aGeom2SizeIter++){
            const EGeometrieElement& aGeom = aGeom2SizeIter->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<TInt> 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){
index 67d2cbe25d52a80c130d292d517300fad625a684..a9da97d62fc8c3328de6e857772632694960d5b0 100644 (file)
@@ -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;
       }
index 350144b07b4ba83574004d1a20f80202597b94ad..941a7222796428c486cb86b48c1dd46e7a60e4c1 100644 (file)
@@ -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
index bf40922dd0fc76ef91285861799738bfe32e81e5..9c48382748d983e54b6c25418aa5ec990639974b 100644 (file)
 #include <map>
 using namespace std;
 
+#ifndef WIN32
+#include <sys/sysinfo.h>
+#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<SMDS_MeshEdge*>(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;
 }
-
index 2cdf3749b9f46c8ec8b0cd08c993f7e4990ce695..1a1ef117e88649ab33812a69dbea243ec570c78d 100644 (file)
@@ -482,6 +482,13 @@ public:
   const SMDS_MeshFace *FindFace(std::vector<int> nodes_ids) const;
   static const SMDS_MeshFace* FindFace(std::vector<const SMDS_MeshNode *> 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;
index 207cf7210799f6dfe54261801d75cee92f89b2ce..d354e130ebcd83364737ba7389dd011dc14e84e1 100755 (executable)
@@ -36,4 +36,4 @@
  #define SMDS_EXPORT
 #endif
 
-#endif
\ No newline at end of file
+#endif
index b27055c3145e97ac1012181dde43f656de74660f..f08fd85e74432d4640b402d3f6469e9d938109c8 100644 (file)
@@ -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()
    */
index fa7fc282fdfb8710d4d1db3c546ea5141274c93c..dfde6865af8b10caa5f6a637299d1c7542bb5e31 100644 (file)
@@ -30,6 +30,7 @@
 #include <BRepTools_WireExplorer.hxx>
 #include <BRep_Builder.hxx>
 #include <BRep_Tool.hxx>
+#include <Bnd_Box.hxx>
 #include <Extrema_ExtPC.hxx>
 #include <Extrema_POnCurv.hxx>
 #include <Geom2d_Curve.hxx>
@@ -45,6 +46,8 @@
 #include <gp_Trsf.hxx>
 #include <gp_Vec.hxx>
 #include <math_FunctionSetRoot.hxx>
+#include <math_Matrix.hxx>
+#include <math_Vector.hxx>
 
 #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<gp_XYZ>& 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])  +
+           * (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]) + 
+     * (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( "<<theXYZ(1)<<", "<<theXYZ(2)<<", "<<theXYZ(3)<<")");
-
   gp_XYZ P, params( theXYZ(1), theXYZ(2), theXYZ(3) );
   if ( params.IsEqual( myParam, DBL_MIN )) { // same param
-    theFxyz( 1 ) = myValues[ 0 ];
-    theDf( 1,1 ) = myValues[ 1 ];
-    theDf( 1,2 ) = myValues[ 2 ];
-    theDf( 1,3 ) = myValues[ 3 ];
+    theFxyz( 1 )      = funcValue( myValues[ SQUARE_DIST ] );
+    theDf( 1, DRV_1 ) = myValues[ DRV_1 ];
+    theDf( 1, DRV_2 ) = myValues[ DRV_2 ];
+    theDf( 1, DRV_3 ) = myValues[ DRV_3 ];
     return true;
   }
 #ifdef DEBUG_PARAM_COMPUTE
   cout << "PARAM GUESS: " << params.X() << " "<< params.Y() << " "<< params.X() << endl;
+  myNbIterations++; // how many times call ShellPoint()
 #endif
   ShellPoint( params, P );
-  //myNbIterations++; // how many time call ShellPoint()
 
   gp_Vec dP( myPoint, P );
-  theFxyz(1) = SQRT_FUNC ? dP.SquareMagnitude() : dP.Magnitude();
-  if ( theFxyz(1) < 1e-6 ) {
-    myParam      = params;
-    myValues[ 0 ]= 0;
-    theDf( 1,1 ) = 0;
-    theDf( 1,2 ) = 0;
-    theDf( 1,3 ) = 0;
+  double sqDist = dP.SquareMagnitude();
+  theFxyz(1) = funcValue( sqDist );
+
+  if ( sqDist < myTolerance * myTolerance ) { // a solution found
+    myParam = params;
+    myValues[ SQUARE_DIST ] = sqDist;
+    theFxyz(1)  = theDf( 1,1 ) = theDf( 1,2 ) = theDf( 1,3 ) = 0;
     return true;
   }
 
-  if ( theFxyz(1) < myValues[0] ) // a better guess
+  if ( sqDist < myValues[ SQUARE_DIST ] ) // a better guess
   {
     // 3 partial derivatives
     gp_Vec drv[ 3 ]; // where we move with a small step in each direction
     for ( int iP = 1; iP <= 3; iP++ ) {
-      if ( iP - 1 == myFaceIndex ) {
+      if ( iP == myFaceIndex ) {
         drv[ iP - 1 ] = gp_Vec(0,0,0);
         continue;
       }
@@ -513,44 +534,96 @@ Standard_Boolean SMESH_Block::Values(const math_Vector& theXYZ,
       drv[ iP - 1 ] = dPi;
     }
     for ( int iP = 0; iP < 3; iP++ ) {
+#if 1
       theDf( 1, iP + 1 ) = dP * drv[iP];
-        // 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;
-//         }
+#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<math_FunctionSetWithDerivatives*>(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() <<" )"<<endl
+       << " ------ DIST : " << distance() << "\t Tol=" << myTolerance << "\t Nb LOOPS=" << nbLoops << endl
+       << " ------ NB IT: " << myNbIterations << ",  SUM DIST: " << mySumDist << endl;
+#endif
+
+  theParams = myParam;
+
+  if ( myFaceIndex > 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( "
-//           <<thePoint.X()<<", "<<thePoint.Y()<<", "<<thePoint.Z()<<")");
-  myPoint = thePoint.XYZ();
-
-  myParam.SetCoord( -1,-1,-1 );
-  myValues[0] = 1e100;
-
   const bool isOnFace = IsFaceID( theShapeID );
   double * coef = GetShapeCoef( theShapeID );
 
-  // the first guess
-  math_Vector start( 1, 3, 0.0 );
-  if ( !myGridComputed )
+  // Find the first guess paremeters
+
+  gp_XYZ start(0, 0, 0);
+
+  bool hasHint = ( 0 <= theParamsHint.X() && theParamsHint.X() <= 1 &&
+                   0 <= theParamsHint.Y() && theParamsHint.Y() <= 1 &&
+                   0 <= theParamsHint.Y() && theParamsHint.Y() <= 1 );
+  if ( !hasHint && !myGridComputed )
   {
     // define the first guess by thePoint projection on lines
     // connecting vertices
@@ -600,6 +672,7 @@ bool SMESH_Block::ComputeParameters(const gp_Pnt& thePoint,
         iEdge += 4;
         continue;
       }
+      double sumParam = 0;
       for ( int iE = 0; iE < 4; iE++, iEdge++ ) { // loop on 4 parallel edges
         gp_Pnt p0 = myEdge[ iEdge ].Point( par000 );
         gp_Pnt p1 = myEdge[ iEdge ].Point( par111 );
@@ -613,24 +686,33 @@ bool SMESH_Block::ComputeParameters(const gp_Pnt& thePoint,
             break;
           }
         }
-        start( iParam ) += par;
+        sumParam += par;
       }
-      start( iParam ) /= 4.;
+      start.SetCoord( iParam, sumParam / 4.);
     }
     if ( needGrid ) {
       // compute nodes of 3 x 3 x 3 grid
       int iNode = 0;
+      Bnd_Box box;
       for ( double x = 0.25; x < 0.9; x += 0.25 )
         for ( double y = 0.25; y < 0.9; y += 0.25 )
           for ( double z = 0.25; z < 0.9; z += 0.25 ) {
             TxyzPair & prmPtn = my3x3x3GridNodes[ iNode++ ];
             prmPtn.first.SetCoord( x, y, z );
             ShellPoint( prmPtn.first, prmPtn.second );
+            box.Add( gp_Pnt( prmPtn.second ));
           }
       myGridComputed = true;
+      myTolerance = sqrt( box.SquareExtent() ) * 1e-5;
     }
   }
-  if ( myGridComputed ) {
+
+  if ( hasHint )
+  {
+    start = theParamsHint;
+  }
+  else if ( myGridComputed )
+  {
     double minDist = DBL_MAX;
     gp_XYZ* bestParam = 0;
     for ( int iNode = 0; iNode < 27; iNode++ ) {
@@ -641,59 +723,103 @@ bool SMESH_Block::ComputeParameters(const gp_Pnt& thePoint,
         bestParam = & prmPtn.first;
       }
     }
-    start( 1 ) = bestParam->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 " <<thePoint.X()<<" "<<thePoint.Y()<<" "<<thePoint.Z()<<" ####"<< endl;
-  cout << " ** START ** " << start(1) << " " << start(2) << " " << start(3) << " " << endl;
 #endif
-  int nbLoops = 0;
-  while ( myValues[0] > 1e-1 && nbLoops++ < 10 ) {
-    paramSearch.Perform ( *static_cast<math_FunctionSetWithDerivatives*>(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: ( "<<solution.X()<<" "<<solution.Y()<<" "<<solution.Z()<<" )"<<endl
+       << " ------ DIST : " << sqrt( sqDistance ) << "\t Tol=" << myTolerance << "\t Nb LOOPS=" << nbLoops << endl
+       << " ------ NB IT: " << myNbIterations << ",  SUM DIST: " << mySumDist << endl;
 #endif
-//   MESSAGE( endl << myParam.X() << " " << myParam.Y() << " " << myParam.Z() << endl);
-//   mySumDist += myValues[0];
-//   MESSAGE( " TOTAL NB ITERATIONS: " << myNbIterations <<
-//             " DIST: " << ( SQRT_FUNC ? sqrt(mySumDist) : mySumDist ));
 
-  if ( myFaceIndex >= 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( "<<myParam.X()<<", "<<
-//           myParam.Y()<<", "<<myParam.Z()<<") DISTANCE: " << myValues[0]);
-  return myValues[0] < 1e-1;
-}
-
 //=======================================================================
 //function : DumpShapeID
 //purpose  : debug an id of a block sub-shape
@@ -1067,7 +1181,7 @@ bool SMESH_Block::LoadMeshBlock(const SMDS_MeshVolume*        theVolume,
     TFace& tFace = myFace[ iF - ID_FirstF ];
     vector< int > 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 );
   }
 }
-
index 392160279d415fd71c5be80062cc48d9816b69ee..c5bbc1e2f6561a448fec1b44dd433e362c18a609 100644 (file)
 
 #include "SMESH_SMESH.hxx"
 
-#include <Geom2d_Curve.hxx>
-#include <Geom_Curve.hxx>
-#include <Geom_Surface.hxx>
+//#include <Geom2d_Curve.hxx>
+//#include <Geom_Curve.hxx>
+//#include <Geom_Surface.hxx>
+
 #include <TopExp.hxx>
 #include <TopTools_IndexedMapOfOrientedShape.hxx>
 #include <TopoDS_Edge.hxx>
 #include <TopoDS_Face.hxx>
 #include <TopoDS_Shell.hxx>
 #include <TopoDS_Vertex.hxx>
-#include <gp_Pnt.hxx>
-#include <gp_Trsf.hxx>
 #include <gp_XY.hxx>
 #include <gp_XYZ.hxx>
 #include <math_FunctionSetWithDerivatives.hxx>
-#include <math_Matrix.hxx>
-#include <math_Vector.hxx>
 
 #include <ostream>
 #include <vector>
@@ -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<gp_XYZ,gp_XYZ> TxyzPair;
   TxyzPair my3x3x3GridNodes[ 27 ]; // to compute the first param guess
index 3c34f2e63ef77685268dade7d3f02e6b4c8c672a..f3f25d9e254209160f6c6bcdabcd190f69c59485 100644 (file)
@@ -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");
index ca883167ef71e953dcb919e0f22f89de0c86f0ee..041166d41c0be369754f6ce706026b0c7cedaa4a 100644 (file)
@@ -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();
 
index 0f464bf0f9adad71a6c407f4f92c7c70d5ec53db..a2a4dcbb515b023a1683316d7218e7b3e39bc7d8 100644 (file)
@@ -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 <theMainEdge>
- */
-//=============================================================================
-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 <theMainEdge>
-  SMESH_IndexedMapOfShape& aChain = _mapPropagationChains.ChangeFromKey(theMainEdge);
-  if (aChain.Extent() > 0) {
-    CleanMeshOnPropagationChain(theMainEdge);
-    aChain.Clear();
-  }
-
-  // At first put <theMainEdge> 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 <anE>
-      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 );
index d9538fe86d4ee26719b3e2fbcd0b9916c560dd31..ba122d08bd6480189beeef466166a97de316a87d 100644 (file)
@@ -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 <theEdge>
-
-  bool IsPropagatedHypothesis (const TopoDS_Shape& theEdge,
-                               TopoDS_Shape&       theMainEdge);
-  // Returns true, if a local 1D hypothesis is
-  // propagated on <theEdge> from some other edge.
-  // Returns through <theMainEdge> the edge, from
-  // which the 1D hypothesis is propagated on <theEdge>
-
-  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&) {};
index 5ff5f6d17e89d721ad74302206086a462020963a..8c2eec1067abb7a6797e72ac7b5ad82deb4099b7 100644 (file)
@@ -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<const SMDS_MeshNode*>( 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<const SMDS_MeshNode*>( 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<const SMDS_MeshNode*>() );
       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<const SMDS_MeshElement*>& theSide1,
index 6afe18300eeaf0505a3d6c92cef1a36a0f3d11b1..024a93e5d6de6aea4636dc0c3f9b538baaa34a7c 100644 (file)
@@ -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() ));
+        }
       }
     }
   }
index 7798a0e122a61243f4ddd81a8fa63015ed0e7af8..ad3a1e8f82fc7685b54f4dbd21d347b61b227107 100644 (file)
@@ -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)
index 44396d2afbd43cc0d247785edf3431f7148ea1a8..5054f554906674af055a3c2f6f5684437ef018bf 100644 (file)
@@ -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 <theFace>. The first key-point
+//           will be mapped into <theNodeIndexOnKeyPoint1>-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 <theNodeIndexOnKeyPoint1>-th node
 //=======================================================================
 
-bool SMESH_Pattern::Apply (std::set<const SMDS_MeshFace*>& theFaces,
+bool SMESH_Pattern::Apply (SMESH_Mesh*                     theMesh,
+                           std::set<const SMDS_MeshFace*>& theFaces,
                            const int                       theNodeIndexOnKeyPoint1,
                            const bool                      theReverse)
 {
@@ -2725,11 +2888,29 @@ bool SMESH_Pattern::Apply (std::set<const SMDS_MeshFace*>& 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<const SMDS_MeshFace*>::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 );
   }
index 9699064ad5567b4cd7419a7af28fcf36d06d9530..df1ccd0eb38e130aab7e0b004e0e5aff12400b3c 100644 (file)
@@ -103,7 +103,17 @@ class SMESH_EXPORT SMESH_Pattern {
   // the loaded pattern to <theFace>. The first key-point
   // will be mapped into <theNodeIndexOnKeyPoint1>-th node
 
-  bool Apply (std::set<const SMDS_MeshFace*>& 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 <theFace>. The first key-point
+  // will be mapped into <theNodeIndexOnKeyPoint1>-th node
+
+  bool Apply (SMESH_Mesh*                     theMesh,
+              std::set<const SMDS_MeshFace*>& theFaces,
               const int                       theNodeIndexOnKeyPoint1,
               const bool                      theReverse);
   // Compute nodes coordinates applying
index 6b358d32961ce3e1bf1106b2c088e96175631533..e766df8ef2fe79bb2a510792ddff1bf746c0b75e 100644 (file)
 #include <TopoDS_Compound.hxx>
 #include <gp_Pnt.hxx>
 
-#include <Standard_Failure.hxx>
+#include <Standard_OutOfMemory.hxx>
 #include <Standard_ErrorHandler.hxx>
 
 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<SMESH_Algo*> (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 )
index 1231c490c03ca963b013da4596ba87b07b3d9f22..fa885cefdbdad61078dd4b66cad3f4a11ada0919 100644 (file)
@@ -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;
index fdef18da93699ea83b634ee1798817838bc81e8f..6747798efb951bf1a8aab55d3c8d9bc736997f95 100755 (executable)
@@ -36,4 +36,4 @@
  #define SMESHDS_EXPORT
 #endif
 
-#endif
\ No newline at end of file
+#endif
index 89ce6fe7a9880b49a2f379d8650046e5c2b9fae2..9cedb02fa7ac8a9d8d64fe66a8dc89c8c02011f6 100644 (file)
@@ -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<SMESH::SMESH_Hypothesis>(selected.First());
+        Handle(SALOME_InteractiveObject) anIObject = selected.First();
+       SMESH::SMESH_Hypothesis_var aHypothesis = SMESH::IObjectToInterface<SMESH::SMESH_Hypothesis>(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 );
index 5ce9868764a3ea9944b89d288f0f4c1a2e98eee2..6c856bb78eee8556423c4e540e2abcf25500d51e 100644 (file)
@@ -77,6 +77,7 @@
 #include <qtable.h>
 #include <qhbox.h>
 #include <qhgroupbox.h>
+#include <qvgroupbox.h>
 
 #include <vtkProperty.h>
 
@@ -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();
 }
 
index bb4252475d2fce3d712a4ff6225f8024339c1614..5e22e2b5a9d1a1c2f22595f4924ea0fcc06cc10e 100644 (file)
@@ -130,6 +130,7 @@ private:
   QFrame*                      createMainFrame   (QWidget*);
 
   QLabel*                      myMeshName;
+  QGroupBox*                   myMemoryLackGroup;
   QGroupBox*                   myErrorGroup;
   QTable*                      myTable;
   QPushButton*                 myShowBtn;
index 2b75ac0c4025963d4d22d59957684bd1c5d35c79..59a3eda1af408f176f17607824a2e7317d3f7616 100755 (executable)
@@ -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());
     }
 }
 
index e94a8a99394c281a4a9b1af76c3039f9d1ede6fc..7414bf5ff6d4cb5feea58cd308cfe763c4f3730e 100644 (file)
@@ -45,8 +45,8 @@
 
 #include <qapplication.h>
 
-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<listSOmesh.size(); i++ )
+    for( int i = 0; i < listSOmesh.size(); i++ )
     {
       _PTR(SObject) submSO = listSOmesh[i];
       SMESH::SMESH_Mesh_var aMesh = SMESH::SObjectToInterface<SMESH::SMESH_Mesh>( 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<SMESHGUI_GenericHypothesisCreator*>( 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;
index c76e409e1a2963ff5c324349ad136c9244954329..b411cf7b893f2ce613914fbd4cf86ea2b149a683 100644 (file)
@@ -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;
 };
 
index 114b8dbc3c274ed9a550d96443f255fc38391fd0..4be1a4cbb6fd374904bd5956231b97c3d492414f 100644 (file)
@@ -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<SalomeApp_Application*>(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:
index b21ad3260cb676f1668fe1d39c308d672a133d16..22cbb72936fa5b6c1f225da88ff7bc5466b87891 100644 (file)
@@ -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
 
index 9aa469e68ccf909ef99a60a3f68957f6ebad73ae..ca82f9dd3207a601558ebc0d1c24e0857233098a 100644 (file)
@@ -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<SMESH::SMESH_Hypothesis_var>& 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<SMESH::SMESH_Hypothesis_var> 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<SMESH::SMESH_Hypothesis_var>& aHypVarList = myExistingHyps[ theDim ][ Algo ];
-  QValueList<SMESH::SMESH_Hypothesis_var>::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<SMESH::SMESH_Hypothesis_var>& 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<SMESH::SMESH_Hypothesis_var>& theHypList ) const
+                           const THypList& theHypList ) const
 {
   int aRes = -1;
   if ( !theHyp->_is_nil() )
   {
     int i = 0;
-    QValueList<SMESH::SMESH_Hypothesis_var>::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
index 190c386dd77a33232e7722b9206f916a33a09f63..23365fd1a0c7033fff884284a20a415f40de3ed0 100644 (file)
 #include "SMESH_SMESHGUI.hxx"
 
 #include "SMESHGUI_SelectionOp.h"
-#include <qstringlist.h>
 
 #include <SALOMEconfig.h>
 #include CORBA_SERVER_HEADER(GEOM_Gen)
 #include CORBA_SERVER_HEADER(SMESH_Mesh)
 
+#include <qstringlist.h>
+
 class SMESHGUI_MeshDlg;
 class SMESHGUI_ShapeByMeshOp;
 class HypothesisData;
@@ -58,6 +59,15 @@ public:
 
   enum HypType{ Algo = 0, MainHyp, AddHyp, NbHypTypes };
 
+  typedef std::pair<SMESH::SMESH_Hypothesis_var, QString> 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<SMESH::SMESH_Hypothesis_var>& 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<SMESH::SMESH_Hypothesis_var>& ) 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<SMESH::SMESH_Hypothesis_var> > 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
index 8eb5e67cece16eaef81766b254d58472d5776c12..2c69a8161282e7bd17dface9830318388fbacce1 100644 (file)
@@ -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);
index b89009898cd88a49bd08ff2f08c09a682757b83f..357ee5889b79afa1db0b2dee230a09c4b52445b4 100644 (file)
@@ -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);
index cc5c996893f5038f8c248f43cd78a4be5efc8124..53069b718412e4a23a80b61ef86cc09790e2b16d 100644 (file)
@@ -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
index bf4fd6d9861277f742fa1606829a27d6dfa2e10e..c00e097d76683e08b8aec32b3beb36c1c61c1c44 100644 (file)
@@ -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);
index 4ef2f345a78f1c6e4d7311b9e588756ef87e8935..df115b10501898ba7b48e8ca436401010cc4a685 100644 (file)
@@ -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"
 
index 3cd0dd18a0724af4a3bf934667954765c05a38a3..998266806c6a5fb5cbf932c74eafd54a1259bb70 100644 (file)
@@ -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<TCollection_AsciiString>
+  {
+    /*!
+     * \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_<nb> = 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 = <theMesh or algo>.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 <geom> 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 <vertex>
       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...
index 2f1bc027c5abed7015147b8c1b17f7433ea06565..a09a84cd645a8be5e595505bbc49e5dc1d45a542 100644 (file)
 
 // ===========================================================================================
 /*!
- * \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<TCollection_AsciiString, TCollection_AsciiString > 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<Handle(_pyCommand)>  myArgCommands;
   std::list<Handle(_pyCommand)>  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<Handle(_pyCommand)>& 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();
 
index 85cec50a5875f8c06469cd974070ebe44364fcdc..51bc29f22bd7c836fb5fbe71a72e17264c7c01f2 100644 (file)
@@ -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<<","<<aCompare<<","<<aThreshold<<",'"<<aThresholdStr<<"','"<<aThresholdID<<"',"<<
-      aUnary<<","<<aBinary<<","<<aTolerance<<","<<aTypeOfElem<<","<<aPrecision<<"))";
+    TPythonDump() << "aCriterion = SMESH.Filter.Criterion(" << aCriterion << "," << aCompare
+                  << "," << aThreshold << ",'" << aThresholdStr << "',salome.ObjectToID("
+                  << aThresholdID << ")," << aUnary << "," << aBinary << "," << aTolerance
+                  << "," << aTypeOfElem << "," << aPrecision << ")";
 
     SMESH::Predicate_ptr aPredicate = SMESH::Predicate::_nil();
     SMESH::NumericalFunctor_ptr aFunctor = SMESH::NumericalFunctor::_nil();
index a387b1c65ef83239583f48af56125bff0db1d1c3..cf94c0ec7530b86d02e5d21ad0d4a9aa5620cf4a 100644 (file)
@@ -126,7 +126,7 @@ static int MYDEBUG = 0;
 #endif
 
 // Static variables definition
-GEOM::GEOM_Gen_var      SMESH_Gen_i::myGeomGen=GEOM::GEOM_Gen::_nil();
+GEOM::GEOM_Gen_var      SMESH_Gen_i::myGeomGen = GEOM::GEOM_Gen::_nil();
 CORBA::ORB_var          SMESH_Gen_i::myOrb;
 PortableServer::POA_var SMESH_Gen_i::myPoa;
 SALOME_NamingService*   SMESH_Gen_i::myNS  = NULL;
@@ -223,12 +223,14 @@ SALOME_LifeCycleCORBA*  SMESH_Gen_i::GetLCC() {
  *  Get GEOM::GEOM_Gen reference
  */
 //=============================================================================     
-GEOM::GEOM_Gen_ptr SMESH_Gen_i::GetGeomEngine()
-{
-  if (CORBA::is_nil(myGeomGen))
+GEOM::GEOM_Gen_ptr SMESH_Gen_i::GetGeomEngine() {
+  //CCRT GEOM::GEOM_Gen_var aGeomEngine =
+  //CCRT   GEOM::GEOM_Gen::_narrow( GetLCC()->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<SMESH_Mesh_i*>( 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();
index e76000901dd85103799c487127ab54c4c30fcf99..d179f62d1ded9d7011f3e51f55d767f3bd7acd98 100644 (file)
@@ -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"
 
index 76e5a982179c651bdd6ca5b1f42b610154bb5f60..d10e9014114cf702cb973ea2b7c5d13edd497260 100644 (file)
@@ -52,6 +52,7 @@
 #include "SMESH_MeshEditor.hxx"
 
 // OCCT Includes
+#include <BRep_Builder.hxx>
 #include <OSD_Path.hxx>
 #include <OSD_File.hxx>
 #include <OSD_Directory.hxx>
@@ -59,7 +60,8 @@
 #include <TColStd_MapOfInteger.hxx>
 #include <TColStd_MapIteratorOfMapOfInteger.hxx>
 #include <TColStd_SequenceOfInteger.hxx>
-#include "TCollection_AsciiString.hxx"
+#include <TCollection_AsciiString.hxx>
+#include <TopoDS_Compound.hxx>
 
 // STL Includes
 #include <string>
@@ -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<TopoDS_Shape> & 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<int, ::SMESH_subMesh*>::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<int, SMESH::SMESH_subMesh_ptr>::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<TopoDS_Shape>::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 <const SMESHDS_Hypothesis * > hyps = _impl->GetHypothesisList(oldGroupShape);
+      list <const SMESHDS_Hypothesis * >::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 );
+      }
+    }
+  }
+}
+
 //=============================================================================
 /*!
  *
index af50b569bc6f7973efc9942aa92884915de57666..8ad4793767e003ea0a11c811bc63626c36d266d5 100644 (file)
 
 #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 <map>
 
@@ -312,6 +313,13 @@ public:
   const map<int, SMESH::SMESH_GroupBase_ptr>& 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();
index 13ed3ac891d890c147c9a0742bb93a2253c0faa5..4f730b3874abf276c3f99be4bab1cda2f4d6529a 100644 (file)
@@ -40,6 +40,9 @@
 #include <TopoDS.hxx>
 #include <TopoDS_Face.hxx>
 
+#include <Standard_Failure.hxx>
+#include <Standard_ErrorHandler.hxx>
+
 #include <sstream>
 #include <set>
 
@@ -286,8 +289,24 @@ SMESH::point_array*
     if ( elem && elem->GetType() == SMDSAbs_Face )
       fset.insert( static_cast<const SMDS_MeshFace *>( 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<const gp_XYZ *>::iterator xyzIt = xyzList.begin();
index 6e65a3d4149dbc15a4c23c669641f0e3efb55da6..518e1be9220ca88703e8707d5aea712a20ac264f 100644 (file)
 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
index 4df569cb6ba46c1461f203ee2cdb73fe8365b7ce..da14ee1f78247bd32654d4f30b7d4e3b2aceabe8 100644 (file)
@@ -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) {
index 808b07cb68d21dad3197e91aebb8dbf8e3f0e47e..154ffd7a2c5fdd6d9faa4a08c9dc85b609bd60ba 100644 (file)
@@ -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
index 9092d08110d514a9f5929ec96f6fd812ca026e67..09ab5553d3e233bee9d930792c7505c8f25c3818 100644 (file)
 
 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
-# <prefix>/lib/python<version>/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 (file)
index 247c0fc..0000000
+++ /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"
-
index 5b6ee694b951da7e909fd40048b93ffb3ddbb006..d9881a6a7a0ddb656b0e64f5e9991945c0f7676b 100644 (file)
@@ -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<n:
-            a = a + s + str(args[i])
-            s = ","
-            i = i + 1
-        name = GetName(self.geom)
-        SetName(hypo, name + "/" + hyp + a)
+    def Hypothesis(self, hyp, args=[], so="libStdMeshersEngine.so", UseExisting=0):
+        CreateNew = 1
+        if UseExisting:
+            hypo = self.FindHypothesis(hyp, args)
+            if hypo!=None: CreateNew = 0
+            pass
+        if CreateNew:
+            hypo = smesh.CreateHypothesis(hyp, so)
+            key = "%s %s %s" % (self.__class__.__name__, hyp, args)
+            Mesh_Algorithm.hypos[key] = hypo
+            a = ""
+            s = "="
+            i = 0
+            n = len(args)
+            while i<n:
+                a = a + s + str(args[i])
+                s = ","
+                i = i + 1
+                name = GetName(self.geom)
+            #SetName(hypo, name + "/" + hyp + a) - NPAL16198
+            SetName(hypo, hyp + a)
+            pass
         status = self.mesh.mesh.AddHypothesis(self.geom, hypo)
-        TreatHypoStatus( status, hyp, name, 0 )
+        TreatHypoStatus( status, hyp, GetName(hypo), 0 )
         return hypo
 
 
@@ -490,25 +517,35 @@ class Mesh_Algorithm:
 #  More details.
 class Mesh_Segment(Mesh_Algorithm):
 
+    algo = 0 # algorithm object common for all Mesh_Segment's
+
     ## Private constructor.
     def __init__(self, mesh, geom=0):
-        self.Create(mesh, geom, "Regular_1D")
-        
+        if not Mesh_Segment.algo:
+            Mesh_Segment.algo = self.Create(mesh, geom, "Regular_1D")
+        else:
+            self.Assign( Mesh_Segment.algo, mesh, geom)
+            pass
+
     ## Define "LocalLength" hypothesis to cut an edge in several segments with the same length
     #  @param l for the length of segments that cut an edge
-    def LocalLength(self, l):
-        hyp = self.Hypothesis("LocalLength", [l])
+    #  @param UseExisting if ==true - search existing hypothesis created with
+    #                     same parameters, else (default) - create new
+    def LocalLength(self, l, UseExisting=0):
+        hyp = self.Hypothesis("LocalLength", [l], UseExisting=UseExisting)
         hyp.SetLength(l)
         return hyp
         
     ## Define "NumberOfSegments" hypothesis to cut an edge in several fixed number of segments
     #  @param n for the number of segments that cut an edge
     #  @param s for the scale factor (optional)
-    def NumberOfSegments(self, n, s=[]):
+    #  @param UseExisting if ==true - search existing hypothesis created with
+    #                     same parameters, else (default) - create new
+    def NumberOfSegments(self, n, s=[], UseExisting=0):
         if s == []:
-            hyp = self.Hypothesis("NumberOfSegments", [n])
+            hyp = self.Hypothesis("NumberOfSegments", [n], UseExisting=UseExisting)
         else:
-            hyp = self.Hypothesis("NumberOfSegments", [n,s])
+            hyp = self.Hypothesis("NumberOfSegments", [n,s], UseExisting=UseExisting)
             hyp.SetDistrType( 1 )
             hyp.SetScaleFactor(s)
         hyp.SetNumberOfSegments(n)
@@ -517,8 +554,10 @@ class Mesh_Segment(Mesh_Algorithm):
     ## Define "Arithmetic1D" hypothesis to cut an edge in several segments with arithmetic length increasing
     #  @param start for the length of the first segment
     #  @param end   for the length of the last  segment
-    def Arithmetic1D(self, start, end):
-        hyp = self.Hypothesis("Arithmetic1D", [start, end])
+    #  @param UseExisting if ==true - search existing hypothesis created with
+    #                     same parameters, else (default) - create new
+    def Arithmetic1D(self, start, end, UseExisting=0):
+        hyp = self.Hypothesis("Arithmetic1D", [start, end], UseExisting=UseExisting)
         hyp.SetLength(start, 1)
         hyp.SetLength(end  , 0)
         return hyp
@@ -526,35 +565,43 @@ class Mesh_Segment(Mesh_Algorithm):
     ## Define "StartEndLength" hypothesis to cut an edge in several segments with geometric length increasing
     #  @param start for the length of the first segment
     #  @param end   for the length of the last  segment
-    def StartEndLength(self, start, end):
-        hyp = self.Hypothesis("StartEndLength", [start, end])
+    #  @param UseExisting if ==true - search existing hypothesis created with
+    #                     same parameters, else (default) - create new
+    def StartEndLength(self, start, end, UseExisting=0):
+        hyp = self.Hypothesis("StartEndLength", [start, end], UseExisting=UseExisting)
         hyp.SetLength(start, 1)
         hyp.SetLength(end  , 0)
         return hyp
         
     ## Define "Deflection1D" hypothesis
     #  @param d for the deflection
-    def Deflection1D(self, d):
-        hyp = self.Hypothesis("Deflection1D", [d])
+    #  @param UseExisting if ==true - search existing hypothesis created with
+    #                     same parameters, else (default) - create new
+    def Deflection1D(self, d, UseExisting=0):
+        hyp = self.Hypothesis("Deflection1D", [d], UseExisting=UseExisting)
         hyp.SetDeflection(d)
         return hyp
         
     ## Define "Propagation" hypothesis that propagate all other hypothesis on all others edges that are in
     #  the opposite side in the case of quadrangular faces
     def Propagation(self):
-        return self.Hypothesis("Propagation")
+        return self.Hypothesis("Propagation", UseExisting=1)
 
     ## Define "AutomaticLength" hypothesis
     #  @param fineness for the fineness [0-1]
-    def AutomaticLength(self, fineness=0):
-        hyp = self.Hypothesis("AutomaticLength")
+    #  @param UseExisting if ==true - search existing hypothesis created with
+    #                     same parameters, else (default) - create new
+    def AutomaticLength(self, fineness=0, UseExisting=0):
+        hyp = self.Hypothesis("AutomaticLength",[fineness],UseExisting=UseExisting)
         hyp.SetFineness( fineness )
         return hyp
 
     ## Define "SegmentLengthAroundVertex" hypothesis
     #  @param length for the segment length
     #  @param vertex for the length localization: vertex index [0,1] | verext object
-    def LengthNearVertex(self, length, vertex=0):
+    #  @param UseExisting if ==true - search existing hypothesis created with
+    #                     same parameters, else (default) - create new
+    def LengthNearVertex(self, length, vertex=0, UseExisting=0):
         import types
         store_geom = self.geom
         if vertex:
@@ -563,8 +610,8 @@ class Mesh_Segment(Mesh_Algorithm):
                 pass
             self.geom = vertex
             pass
-        hyp = self.Hypothesis("SegmentAroundVertex_0D")
-        hyp = self.Hypothesis("SegmentLengthAroundVertex")
+        hyp = self.Hypothesis("SegmentAroundVertex_0D",[length],UseExisting=UseExisting)
+        hyp = self.Hypothesis("SegmentLengthAroundVertex",[length],UseExisting=UseExisting)
         self.geom = store_geom
         hyp.SetLength( length )
         return hyp
@@ -576,7 +623,7 @@ class Mesh_Segment(Mesh_Algorithm):
     #  The 3D mesher generates quadratic volumes only if all boundary faces
     #  are quadratic ones, else it fails.
     def QuadraticMesh(self):
-        hyp = self.Hypothesis("QuadraticMesh")
+        hyp = self.Hypothesis("QuadraticMesh", UseExisting=1)
         return hyp
 
 # Public class: Mesh_CompositeSegment
@@ -587,10 +634,16 @@ class Mesh_Segment(Mesh_Algorithm):
 #  More details.
 class Mesh_CompositeSegment(Mesh_Segment):
 
+    algo = 0 # algorithm object common for all Mesh_CompositeSegment's
+
     ## Private constructor.
     def __init__(self, mesh, geom=0):
-        self.Create(mesh, geom, "CompositeSegment_1D")
-        
+        if not Mesh_CompositeSegment.algo:
+            Mesh_CompositeSegment.algo = self.Create(mesh, geom, "CompositeSegment_1D")
+        else:
+            self.Assign( Mesh_CompositeSegment.algo, mesh, geom)
+            pass
+
 
 # Public class: Mesh_Segment_Python
 # ---------------------------------
@@ -600,16 +653,24 @@ class Mesh_CompositeSegment(Mesh_Segment):
 #  More details.
 class Mesh_Segment_Python(Mesh_Segment):
 
+    algo = 0 # algorithm object common for all Mesh_Segment_Python's
+
     ## Private constructor.
     def __init__(self, mesh, geom=0):
         import Python1dPlugin
-        self.Create(mesh, geom, "Python_1D", "libPython1dEngine.so")
+        if not Mesh_Segment_Python.algo:
+            Mesh_Segment_Python.algo = self.Create(mesh, geom, "Python_1D", "libPython1dEngine.so")
+        else:
+            self.Assign( Mesh_Segment_Python.algo, mesh, geom)
+            pass
     
     ## Define "PythonSplit1D" hypothesis based on the Erwan Adam patch, awaiting equivalent SALOME functionality
     #  @param n for the number of segments that cut an edge
     #  @param func for the python function that calculate the length of all segments
-    def PythonSplit1D(self, n, func):
-        hyp = self.Hypothesis("PythonSplit1D", [n], "libPython1dEngine.so")
+    #  @param UseExisting if ==true - search existing hypothesis created with
+    #                     same parameters, else (default) - create new
+    def PythonSplit1D(self, n, func, UseExisting=0):
+        hyp = self.Hypothesis("PythonSplit1D", [n], "libPython1dEngine.so", UseExisting=UseExisting)
         hyp.SetNumberOfSegments(n)
         hyp.SetPythonLog10RatioFunction(func)
         return hyp
@@ -622,97 +683,163 @@ class Mesh_Segment_Python(Mesh_Segment):
 #  More details.
 class Mesh_Triangle(Mesh_Algorithm):
 
+    # default values
     algoType = 0
     params = 0
-   
+
+    # algorithm objects common for all instances of Mesh_Triangle
+    algoMEF = 0    
+    algoNET = 0
+    algoNET_2D = 0
+
     ## Private constructor.
     def __init__(self, mesh, algoType, geom=0):
         if algoType == MEFISTO:
-            self.Create(mesh, geom, "MEFISTO_2D")
+            if not Mesh_Triangle.algoMEF:
+                Mesh_Triangle.algoMEF = self.Create(mesh, geom, "MEFISTO_2D")
+            else:
+                self.Assign( Mesh_Triangle.algoMEF, mesh, geom)
+                pass
+            pass
         elif algoType == NETGEN:
             if noNETGENPlugin:
-                print "Warning: NETGENPlugin module has not been imported."
-            self.Create(mesh, geom, "NETGEN_2D", "libNETGENEngine.so")
+                print "Warning: NETGENPlugin module unavailable"
+                pass
+            if not Mesh_Triangle.algoNET:
+                Mesh_Triangle.algoNET = self.Create(mesh, geom, "NETGEN_2D", "libNETGENEngine.so")
+            else:
+                self.Assign( Mesh_Triangle.algoNET, mesh, geom)
+                pass
+            pass
+        elif algoType == NETGEN_2D:
+            if noNETGENPlugin:
+                print "Warning: NETGENPlugin module unavailable"
+                pass
+            if not Mesh_Triangle.algoNET_2D:
+                Mesh_Triangle.algoNET_2D = self.Create(mesh, geom,
+                                                      "NETGEN_2D_ONLY", "libNETGENEngine.so")
+            else:
+                self.Assign( Mesh_Triangle.algoNET_2D, mesh, geom)
+                pass
+            pass
+
         self.algoType = algoType
 
     ## Define "MaxElementArea" hypothesis to give the maximun area of each triangles
     #  @param area for the maximum area of each triangles
-    def MaxElementArea(self, area):
-        if self.algoType == MEFISTO:
-            hyp = self.Hypothesis("MaxElementArea", [area])
+    #  @param UseExisting if ==true - search existing hypothesis created with
+    #                     same parameters, else (default) - create new
+    #
+    #  Only for algoType == MEFISTO || NETGEN_2D
+    def MaxElementArea(self, area, UseExisting=0):
+        if self.algoType == MEFISTO or self.algoType == NETGEN_2D:
+            hyp = self.Hypothesis("MaxElementArea", [area], UseExisting=UseExisting)
             hyp.SetMaxElementArea(area)
             return hyp
         elif self.algoType == NETGEN:
             print "Netgen 1D-2D algo doesn't support this hypothesis"
             return None
-            
+
     ## Define "LengthFromEdges" hypothesis to build triangles based on the length of the edges taken from the wire
+    #
+    #  Only for algoType == MEFISTO || NETGEN_2D
     def LengthFromEdges(self):
-        if self.algoType == MEFISTO:
-            hyp = self.Hypothesis("LengthFromEdges")
+        if self.algoType == MEFISTO or self.algoType == NETGEN_2D:
+            hyp = self.Hypothesis("LengthFromEdges", UseExisting=1)
             return hyp
         elif self.algoType == NETGEN:
             print "Netgen 1D-2D algo doesn't support this hypothesis"
             return None
-        
+
+    ## Set QuadAllowed flag
+    #
+    #  Only for algoType == NETGEN || NETGEN_2D
+    def SetQuadAllowed(self, toAllow=True):
+        if self.algoType == NETGEN_2D:
+            if toAllow: # add QuadranglePreference
+                self.Hypothesis("QuadranglePreference", UseExisting=1)
+            else:       # remove QuadranglePreference
+                for hyp in self.mesh.GetHypothesisList( self.geom ):
+                    if hyp.GetName() == "QuadranglePreference":
+                        self.mesh.RemoveHypothesis( self.geom, hyp )
+                        pass
+                    pass
+                pass
+            return
+        if self.params == 0 and self.Parameters():
+            self.params.SetQuadAllowed(toAllow)
+            return
+
     ## Define "Netgen 2D Parameters" hypothesis
+    #
+    #  Only for algoType == NETGEN
     def Parameters(self):
         if self.algoType == NETGEN:
-            self.params = self.Hypothesis("NETGEN_Parameters_2D", [], "libNETGENEngine.so")
+            self.params = self.Hypothesis("NETGEN_Parameters_2D", [],
+                                          "libNETGENEngine.so", UseExisting=0)
             return self.params
         elif self.algoType == MEFISTO:
-            print "Mefisto algo doesn't support this hypothesis"
+            print "Mefisto algo doesn't support NETGEN_Parameters_2D hypothesis"
+            return None
+        elif self.algoType == NETGEN_2D:
+            print "NETGEN_2D_ONLY algo doesn't support 'NETGEN_Parameters_2D' hypothesis"
+            print "NETGEN_2D_ONLY uses 'MaxElementArea' and 'LengthFromEdges' ones"
             return None
+        return None
 
     ## Set MaxSize
+    #
+    #  Only for algoType == NETGEN
     def SetMaxSize(self, theSize):
-        if self.params == 0:
-            self.Parameters()
-        self.params.SetMaxSize(theSize)
+        if self.params == 0 and self.Parameters():
+            self.params.SetMaxSize(theSize)
         
     ## Set SecondOrder flag
+    #
+    #  Only for algoType == NETGEN
     def SetSecondOrder(self, theVal):
-        if self.params == 0:
-            self.Parameters()
-        self.params.SetSecondOrder(theVal)
+        if self.params == 0 and self.Parameters():
+            self.params.SetSecondOrder(theVal)
+            return
 
     ## Set Optimize flag
+    #
+    #  Only for algoType == NETGEN
     def SetOptimize(self, theVal):
-        if self.params == 0:
-            self.Parameters()
-        self.params.SetOptimize(theVal)
+        if self.params == 0 and self.Parameters():
+            self.params.SetOptimize(theVal)
 
     ## Set Fineness
     #  @param theFineness is:
     #  VeryCoarse, Coarse, Moderate, Fine, VeryFine or Custom
+    #
+    #  Only for algoType == NETGEN
     def SetFineness(self, theFineness):
-        if self.params == 0:
-            self.Parameters()
-        self.params.SetFineness(theFineness)
+        if self.params == 0 and self.Parameters():
+            self.params.SetFineness(theFineness)
         
     ## Set GrowthRate  
+    #
+    #  Only for algoType == NETGEN
     def SetGrowthRate(self, theRate):
-        if self.params == 0:
-            self.Parameters()
-        self.params.SetGrowthRate(theRate)
+        if self.params == 0 and self.Parameters():
+            self.params.SetGrowthRate(theRate)
 
     ## Set NbSegPerEdge
+    #
+    #  Only for algoType == NETGEN
     def SetNbSegPerEdge(self, theVal):
-        if self.params == 0:
-            self.Parameters()
-        self.params.SetNbSegPerEdge(theVal)
+        if self.params == 0 and self.Parameters():
+            self.params.SetNbSegPerEdge(theVal)
 
     ## Set NbSegPerRadius
+    #
+    #  Only for algoType == NETGEN
     def SetNbSegPerRadius(self, theVal):
-        if self.params == 0:
-            self.Parameters()
-        self.params.SetNbSegPerRadius(theVal)
+        if self.params == 0 and self.Parameters():
+            self.params.SetNbSegPerRadius(theVal)
 
-    ## Set QuadAllowed flag
-    def SetQuadAllowed(self, toAllow):
-        if self.params == 0:
-            self.Parameters()
-        self.params.SetQuadAllowed(toAllow)
+    pass
         
     
 # Public class: Mesh_Quadrangle
@@ -723,15 +850,21 @@ class Mesh_Triangle(Mesh_Algorithm):
 #  More details.
 class Mesh_Quadrangle(Mesh_Algorithm):
 
+    algo = 0 # algorithm object common for all Mesh_Quadrangle's
+
     ## Private constructor.
     def __init__(self, mesh, geom=0):
-        self.Create(mesh, geom, "Quadrangle_2D")
+        if not Mesh_Quadrangle.algo:
+            Mesh_Quadrangle.algo = self.Create(mesh, geom, "Quadrangle_2D")
+        else:
+            self.Assign( Mesh_Quadrangle.algo, mesh, geom)
+            pass
     
     ## Define "QuadranglePreference" hypothesis, forcing construction
     #  of quadrangles if the number of nodes on opposite edges is not the same
     #  in the case where the global number of nodes on edges is even
     def QuadranglePreference(self):
-        hyp = self.Hypothesis("QuadranglePreference")
+        hyp = self.Hypothesis("QuadranglePreference", UseExisting=1)
         return hyp
     
 # Public class: Mesh_Tetrahedron
@@ -745,30 +878,55 @@ class Mesh_Tetrahedron(Mesh_Algorithm):
     params = 0
     algoType = 0
 
+    algoNET = 0 # algorithm object common for all Mesh_Tetrahedron's
+    algoGHS = 0 # algorithm object common for all Mesh_Tetrahedron's
+    algoFNET = 0 # algorithm object common for all Mesh_Tetrahedron's
+
     ## Private constructor.
     def __init__(self, mesh, algoType, geom=0):
         if algoType == NETGEN:
-            self.Create(mesh, geom, "NETGEN_3D", "libNETGENEngine.so")
+            if not Mesh_Tetrahedron.algoNET:
+                Mesh_Tetrahedron.algoNET = self.Create(mesh, geom, "NETGEN_3D", "libNETGENEngine.so")
+            else:
+                self.Assign( Mesh_Tetrahedron.algoNET, mesh, geom)
+                pass
+            pass
+
         elif algoType == GHS3D:
-            import GHS3DPlugin
-            self.Create(mesh, geom, "GHS3D_3D" , "libGHS3DEngine.so")
+            if not Mesh_Tetrahedron.algoGHS:
+                import GHS3DPlugin
+                Mesh_Tetrahedron.algoGHS = self.Create(mesh, geom, "GHS3D_3D" , "libGHS3DEngine.so")
+            else:
+                self.Assign( Mesh_Tetrahedron.algoGHS, mesh, geom)
+                pass
+            pass
+
         elif algoType == FULL_NETGEN:
             if noNETGENPlugin:
                 print "Warning: NETGENPlugin module has not been imported."
-            self.Create(mesh, geom, "NETGEN_2D3D", "libNETGENEngine.so")
+            if not Mesh_Tetrahedron.algoFNET:
+                Mesh_Tetrahedron.algoFNET = self.Create(mesh, geom, "NETGEN_2D3D", "libNETGENEngine.so")
+            else:
+                self.Assign( Mesh_Tetrahedron.algoFNET, mesh, geom)
+                pass
+            pass
+
         self.algoType = algoType
 
     ## Define "MaxElementVolume" hypothesis to give the maximun volume of each tetrahedral
     #  @param vol for the maximum volume of each tetrahedral
-    def MaxElementVolume(self, vol):
-        hyp = self.Hypothesis("MaxElementVolume", [vol])
+    #  @param UseExisting if ==true - search existing hypothesis created with
+    #                     same parameters, else (default) - create new
+    def MaxElementVolume(self, vol, UseExisting=0):
+        hyp = self.Hypothesis("MaxElementVolume", [vol], UseExisting=UseExisting)
         hyp.SetMaxElementVolume(vol)
         return hyp
 
     ## Define "Netgen 3D Parameters" hypothesis
     def Parameters(self):
         if (self.algoType == FULL_NETGEN):
-            self.params = self.Hypothesis("NETGEN_Parameters", [], "libNETGENEngine.so")
+            self.params = self.Hypothesis("NETGEN_Parameters", [],
+                                          "libNETGENEngine.so", UseExisting=0)
             return self.params
         else:
             print "Algo doesn't support this hypothesis"
@@ -826,9 +984,15 @@ class Mesh_Tetrahedron(Mesh_Algorithm):
 #  More details.
 class Mesh_Hexahedron(Mesh_Algorithm):
 
+    algo = 0 # algorithm object common for all Mesh_Hexahedron's
+
     ## Private constructor.
     def __init__(self, mesh, geom=0):
-        self.Create(mesh, geom, "Hexa_3D")
+        if not Mesh_Hexahedron.algo:
+            Mesh_Hexahedron.algo = self.Create(mesh, geom, "Hexa_3D")
+        else:
+            self.Assign( Mesh_Hexahedron.algo, mesh, geom)
+            pass
 
 # Deprecated, only for compatibility!
 # Public class: Mesh_Netgen
@@ -844,6 +1008,9 @@ class Mesh_Netgen(Mesh_Algorithm):
 
     is3D = 0
 
+    algoNET23 = 0 # algorithm object common for all Mesh_Netgen's
+    algoNET2 = 0 # algorithm object common for all Mesh_Netgen's
+
     ## Private constructor.
     def __init__(self, mesh, is3D, geom=0):
         if noNETGENPlugin:
@@ -851,16 +1018,29 @@ class Mesh_Netgen(Mesh_Algorithm):
             
         self.is3D = is3D
         if is3D:
-            self.Create(mesh, geom, "NETGEN_2D3D", "libNETGENEngine.so")
+            if not Mesh_Netgen.algoNET23:
+                Mesh_Netgen.algoNET23 = self.Create(mesh, geom, "NETGEN_2D3D", "libNETGENEngine.so")
+            else:
+                self.Assign( Mesh_Netgen.algoNET23, mesh, geom)
+                pass
+            pass
+
         else:
-            self.Create(mesh, geom, "NETGEN_2D", "libNETGENEngine.so")
+            if not Mesh_Netgen.algoNET2:
+                Mesh_Netgen.algoNET2 = self.Create(mesh, geom, "NETGEN_2D", "libNETGENEngine.so")
+            else:
+                self.Assign( Mesh_Netgen.algoNET2, mesh, geom)
+                pass
+            pass
 
     ## Define hypothesis containing parameters of the algorithm
     def Parameters(self):
         if self.is3D:
-            hyp = self.Hypothesis("NETGEN_Parameters", [], "libNETGENEngine.so")
+            hyp = self.Hypothesis("NETGEN_Parameters", [],
+                                  "libNETGENEngine.so", UseExisting=0)
         else:
-            hyp = self.Hypothesis("NETGEN_Parameters_2D", [], "libNETGENEngine.so")
+            hyp = self.Hypothesis("NETGEN_Parameters_2D", [],
+                                  "libNETGENEngine.so", UseExisting=0)
         return hyp
 
 # Public class: Mesh_Projection1D
@@ -871,9 +1051,15 @@ class Mesh_Netgen(Mesh_Algorithm):
 #  More details.
 class Mesh_Projection1D(Mesh_Algorithm):
 
+    algo = 0 # algorithm object common for all Mesh_Projection1D's
+
     ## Private constructor.
     def __init__(self, mesh, geom=0):
-        self.Create(mesh, geom, "Projection_1D")
+        if not Mesh_Projection1D.algo:
+            Mesh_Projection1D.algo = self.Create(mesh, geom, "Projection_1D")
+        else:
+            self.Assign( Mesh_Projection1D.algo, mesh, geom)
+            pass
 
     ## Define "Source Edge" hypothesis, specifying a meshed edge to
     #  take a mesh pattern from, and optionally association of vertices
@@ -883,8 +1069,10 @@ class Mesh_Projection1D(Mesh_Algorithm):
     #  @param srcV is vertex of \a edge to associate with \a tgtV (optional)
     #  @param tgtV is vertex of \a the edge where the algorithm is assigned,
     #  to associate with \a srcV (optional)
-    def SourceEdge(self, edge, mesh=None, srcV=None, tgtV=None):
-        hyp = self.Hypothesis("ProjectionSource1D")
+    #  @param UseExisting if ==true - search existing hypothesis created with
+    #                     same parameters, else (default) - create new
+    def SourceEdge(self, edge, mesh=None, srcV=None, tgtV=None, UseExisting=0):
+        hyp = self.Hypothesis("ProjectionSource1D", [edge,mesh,srcV,tgtV], UseExisting=UseExisting)
         hyp.SetSourceEdge( edge )
         if not mesh is None and isinstance(mesh, Mesh):
             mesh = mesh.GetMesh()
@@ -901,9 +1089,15 @@ class Mesh_Projection1D(Mesh_Algorithm):
 #  More details.
 class Mesh_Projection2D(Mesh_Algorithm):
 
+    algo = 0 # algorithm object common for all Mesh_Projection2D's
+
     ## Private constructor.
     def __init__(self, mesh, geom=0):
-        self.Create(mesh, geom, "Projection_2D")
+        if not Mesh_Projection2D.algo:
+            Mesh_Projection2D.algo = self.Create(mesh, geom, "Projection_2D")
+        else:
+            self.Assign( Mesh_Projection2D.algo, mesh, geom)
+            pass
 
     ## Define "Source Face" hypothesis, specifying a meshed face to
     #  take a mesh pattern from, and optionally association of vertices
@@ -916,10 +1110,14 @@ class Mesh_Projection2D(Mesh_Algorithm):
     #  @param srcV2 is vertex of \a face to associate with \a tgtV1 (optional)
     #  @param tgtV2 is vertex of \a the face where the algorithm is assigned,
     #  to associate with \a srcV2 (optional)
+    #  @param UseExisting if ==true - search existing hypothesis created with
+    #                     same parameters, else (default) - create new
     #
     #  Note: association vertices must belong to one edge of a face
-    def SourceFace(self, face, mesh=None, srcV1=None, tgtV1=None, srcV2=None, tgtV2=None):
-        hyp = self.Hypothesis("ProjectionSource2D")
+    def SourceFace(self, face, mesh=None, srcV1=None, tgtV1=None,
+                   srcV2=None, tgtV2=None, UseExisting=0):
+        hyp = self.Hypothesis("ProjectionSource2D", [face,mesh,srcV1,tgtV1,srcV2,tgtV2],
+                              UseExisting=UseExisting)
         hyp.SetSourceFace( face )
         if not mesh is None and isinstance(mesh, Mesh):
             mesh = mesh.GetMesh()
@@ -935,9 +1133,15 @@ class Mesh_Projection2D(Mesh_Algorithm):
 #  More details.
 class Mesh_Projection3D(Mesh_Algorithm):
 
+    algo = 0 # algorithm object common for all Mesh_Projection3D's
+
     ## Private constructor.
     def __init__(self, mesh, geom=0):
-        self.Create(mesh, geom, "Projection_3D")
+        if not Mesh_Projection3D.algo:
+            Mesh_Projection3D.algo = self.Create(mesh, geom, "Projection_3D")
+        else:
+            self.Assign( Mesh_Projection3D.algo, mesh, geom)
+            pass
 
     ## Define "Source Shape 3D" hypothesis, specifying a meshed solid to
     #  take a mesh pattern from, and optionally association of vertices
@@ -950,10 +1154,15 @@ class Mesh_Projection3D(Mesh_Algorithm):
     #  @param srcV2 is vertex of \a solid to associate with \a tgtV1 (optional)
     #  @param tgtV2 is vertex of \a the solid where the algorithm is assigned,
     #  to associate with \a srcV2 (optional)
+    #  @param UseExisting - if ==true - search existing hypothesis created with
+    #                       same parameters, else (default) - create new
     #
     #  Note: association vertices must belong to one edge of a solid
-    def SourceShape3D(self, solid, mesh=0, srcV1=0, tgtV1=0, srcV2=0, tgtV2=0):
-        hyp = self.Hypothesis("ProjectionSource3D")
+    def SourceShape3D(self, solid, mesh=0, srcV1=0, tgtV1=0,
+                      srcV2=0, tgtV2=0, UseExisting=0):
+        hyp = self.Hypothesis("ProjectionSource3D",
+                              [solid,mesh,srcV1,tgtV1,srcV2,tgtV2],
+                              UseExisting=UseExisting)
         hyp.SetSource3DShape( solid )
         if not mesh is None and isinstance(mesh, Mesh):
             mesh = mesh.GetMesh()
@@ -970,9 +1179,15 @@ class Mesh_Projection3D(Mesh_Algorithm):
 #  More details.
 class Mesh_Prism3D(Mesh_Algorithm):
 
+    algo = 0 # algorithm object common for all Mesh_Prism3D's
+
     ## Private constructor.
     def __init__(self, mesh, geom=0):
-        self.Create(mesh, geom, "Prism_3D")
+        if not Mesh_Prism3D.algo:
+            Mesh_Prism3D.algo = self.Create(mesh, geom, "Prism_3D")
+        else:
+            self.Assign( Mesh_Prism3D.algo, mesh, geom)
+            pass
 
 # Public class: Mesh_RadialPrism
 # -------------------------------
@@ -982,10 +1197,16 @@ class Mesh_Prism3D(Mesh_Algorithm):
 #  More details.
 class Mesh_RadialPrism3D(Mesh_Algorithm):
 
+    algo = 0 # algorithm object common for all Mesh_RadialPrism3D's
+
     ## Private constructor.
     def __init__(self, mesh, geom=0):
-        self.Create(mesh, geom, "RadialPrism_3D")
-        self.distribHyp = self.Hypothesis( "LayerDistribution" )
+        if not Mesh_RadialPrism3D.algo:
+            Mesh_RadialPrism3D.algo = self.Create(mesh, geom, "RadialPrism_3D")
+        else:
+            self.Assign( Mesh_RadialPrism3D.algo, mesh, geom)
+            pass
+        self.distribHyp = self.Hypothesis( "LayerDistribution", UseExisting=0)
         self.nbLayers = None
 
     ## Return 3D hypothesis holding the 1D one
@@ -1007,9 +1228,11 @@ class Mesh_RadialPrism3D(Mesh_Algorithm):
 
     ## Define "NumberOfLayers" hypothesis, specifying a number of layers of
     #  prisms to build between the inner and outer shells
-    def NumberOfLayers(self, n ):
+    #  @param UseExisting if ==true - search existing hypothesis created with
+    #                     same parameters, else (default) - create new
+    def NumberOfLayers(self, n, UseExisting=0):
         self.mesh.GetMesh().RemoveHypothesis( self.geom, self.distribHyp )
-        self.nbLayers = self.Hypothesis("NumberOfLayers")
+        self.nbLayers = self.Hypothesis("NumberOfLayers", [n], UseExisting=UseExisting)
         self.nbLayers.SetNumberOfLayers( n )
         return self.nbLayers
 
@@ -1017,7 +1240,7 @@ class Mesh_RadialPrism3D(Mesh_Algorithm):
     #  to build between the inner and outer shells
     #  @param l for the length of segments
     def LocalLength(self, l):
-        hyp = self.OwnHypothesis("LocalLength", [l])
+        hyp = self.OwnHypothesis("LocalLength", [l] )
         hyp.SetLength(l)
         return hyp
         
@@ -1027,7 +1250,7 @@ class Mesh_RadialPrism3D(Mesh_Algorithm):
     #  @param s for the scale factor (optional)
     def NumberOfSegments(self, n, s=[]):
         if s == []:
-            hyp = self.OwnHypothesis("NumberOfSegments", [n])
+            hyp = self.OwnHypothesis("NumberOfSegments", [n] )
         else:
             hyp = self.OwnHypothesis("NumberOfSegments", [n,s])
             hyp.SetDistrType( 1 )
@@ -1039,7 +1262,7 @@ class Mesh_RadialPrism3D(Mesh_Algorithm):
     #  to build between the inner and outer shells as arithmetic length increasing
     #  @param start for the length of the first segment
     #  @param end   for the length of the last  segment
-    def Arithmetic1D(self, start, end):
+    def Arithmetic1D(self, start, end ):
         hyp = self.OwnHypothesis("Arithmetic1D", [start, end])
         hyp.SetLength(start, 1)
         hyp.SetLength(end  , 0)
@@ -1186,8 +1409,9 @@ class Mesh:
     #  @param geom If defined, subshape to be meshed
     def Segment(self, algo=REGULAR, geom=0):
         ## if Segment(geom) is called by mistake
-        if ( isinstance( algo, geompyDC.GEOM._objref_GEOM_Object)):
+        if isinstance( algo, geompyDC.GEOM._objref_GEOM_Object):
             algo, geom = geom, algo
+            if not algo: algo = REGULAR
             pass
         if algo == REGULAR:
             return Mesh_Segment(self,  geom)
@@ -1201,7 +1425,7 @@ class Mesh:
     ## Creates a triangle 2D algorithm for faces.
     #  If the optional \a geom parameter is not sets, this algorithm is global.
     #  \n Otherwise, this algorithm define a submesh based on \a geom subshape.
-    #  @param algo values are: smesh.MEFISTO or smesh.NETGEN
+    #  @param algo values are: smesh.MEFISTO || smesh.NETGEN_1D2D || smesh.NETGEN_2D
     #  @param geom If defined, subshape to be meshed
     def Triangle(self, algo=MEFISTO, geom=0):
         ## if Triangle(geom) is called by mistake
@@ -1228,6 +1452,7 @@ class Mesh:
         ## if Tetrahedron(geom) is called by mistake
         if ( isinstance( algo, geompyDC.GEOM._objref_GEOM_Object)):
             algo, geom = geom, algo
+            if not algo: algo = NETGEN
             pass
         return Mesh_Tetrahedron(self,  algo, geom)
         
@@ -1381,10 +1606,23 @@ class Mesh:
             geom = self.geom
             pass
         status = self.mesh.AddHypothesis(geom, hyp)
-        isAlgo = ( hyp._narrow( SMESH.SMESH_Algo ) is not None )
+        isAlgo = hyp._narrow( SMESH_Algo )
         TreatHypoStatus( status, GetName( hyp ), GetName( geom ), isAlgo )
         return status
     
+    ## Unassign hypothesis
+    #  @param hyp is a hypothesis to unassign
+    #  @param geom is subhape of mesh geometry
+    def RemoveHypothesis(self, hyp, geom=0 ):
+        if isinstance( hyp, Mesh_Algorithm ):
+            hyp = hyp.GetAlgorithm()
+            pass
+        if not geom:
+            geom = self.geom
+            pass
+        status = self.mesh.RemoveHypothesis(geom, hyp)
+        return status
+
     ## Get the list of hypothesis added on a geom
     #  @param geom is subhape of mesh geometry
     def GetHypothesisList(self, geom):
@@ -1641,7 +1879,7 @@ class Mesh:
     ## Check group names for duplications.
     #  Consider maximum group name length stored in MED file.
     def HasDuplicatedGroupNamesMED(self):
-        return self.mesh.GetStudyId()
+        return self.mesh.HasDuplicatedGroupNamesMED()
         
     ## Obtain instance of SMESH_MeshEditor
     def GetMeshEditor(self):
@@ -1840,6 +2078,10 @@ class Mesh:
     def GetElemNode(self, id, index):
         return self.mesh.GetElemNode(id, index)
 
+    ## Returns IDs of nodes of given element
+    def GetElemNodes(self, id):
+        return self.mesh.GetElemNodes(id)
+
     ## Returns true if given node is medium node
     #  in given quadratic element
     def IsMediumNode(self, elementID, nodeID):
@@ -2085,7 +2327,7 @@ class Mesh:
     #         will be mapped into <theNode000>-th node of each volume, the (0,0,1)
     #         key-point will be mapped into <theNode001>-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 <theNode000>-th node of each volume, the (0,0,1)
     #         key-point will be mapped into <theNode001>-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 (file)
index 0000000..7988a23
--- /dev/null
@@ -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
+# <prefix>/lib/python<version>/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 (file)
index 0000000..247c0fc
--- /dev/null
@@ -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"
+
index 1820f6fe32a6fe75aa199a5b33e931a7f5e8e623..c60cbee617f370ddbdc17d3161f53177320b4ebc 100644 (file)
@@ -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 )
index 85057fb5c49710465d5c8b037ea35e0c753d2fff..3063577c05de8bdc4ca23a044ecdb8ce620b5734 100644 (file)
@@ -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 <Adaptor2d_Curve2d.hxx>
 #include <BRepAdaptor_CompCurve.hxx>
@@ -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;
+}
+
index 1463d2d1fd57aafe415f1414fa4c361ba2bba4f0..43c92bf2b33b01cfc492e4e111d331eb0fd2c935 100644 (file)
@@ -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<UVPtStruct>& GetUVPtStruct(bool isXConst, double constValue) const;
+  const vector<UVPtStruct>& 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<UVPtStruct>& 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
    */
index 80cd6caeb1973e8e309f56e9a914a13586655980..d1567ae0852aad64a8450b6cc68077878e719f15 100644 (file)
@@ -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 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()) <<
index 09aa813033bcd68b1492a6acb087df477081d882..1f1c4042d1964bfd23b6c3cfa00d0a45bb1eb2b2 100644 (file)
@@ -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,
index cb4e61fc161b2a9531355add902b62fcc010982a..ebf2080601532d6238d69b864d941848dc78ee09 100644 (file)
@@ -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: ")<<wires[0]->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")<<wires[0]->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<UVPtStruct>& uvPtVec = wires[ iW ]->GetUVPtStruct(isXConst,constValue);
+    const vector<UVPtStruct>& 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()<<" != "<<wires[ iW ]->NbPoints());
     }
     if ( m + uvPtVec.size()-1 > mefistoToDS.size() ) {
       MESSAGE("Wrong mefistoToDS.size: "<<mefistoToDS.size()<<" < "<<m + uvPtVec.size()-1);
-      return error(dfltErr(),"Internal error");
+      return error("Internal error");
     }
 
     vector<UVPtStruct>::const_iterator uvPt = uvPtVec.begin();
index 8d87d043fdc1240af6c03ddc410ec71f8bf532a5..6d28721e3246bbfd1dd45bb366f8a4ebca28a134 100644 (file)
@@ -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<const TNodeColumn*> & 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<const TNodeColumn*> & 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<const TNodeColumn*> & 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")
                  <<nbNotQuad);
   if ( nbNotQuadMeshed > 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: ")
                  <<nbNotQuadMeshed);
 
   // get found submeshes
@@ -1142,7 +1204,7 @@ bool StdMeshers_PrismAsBlock::Init(SMESH_MesherHelper* helper,
     SMESH_Block::TFace& tFace = myFace[ fID - ID_FirstF ];
     tFace.Set( fID, sideFace->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 );
index 5649199379ba5686ca4cc36116ef4cbe1349031a..d6fab7b38dc0a096c9f94023d7ae39aedebe0577 100644 (file)
@@ -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; }
 };
 
index c276b3afa70705ebc049ab19c2630874c39b7d21..1452599ed08ddc7c25eaf5c8c838ff0d43458aa0 100644 (file)
@@ -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<int,TopoDS_Edge> 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<int,TopoDS_Edge> 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<int,TopoDS_Edge> - propagation step and found edge
  */
 //================================================================================
 
-TopoDS_Edge StdMeshers_ProjectionUtils::GetPropagationEdge( SMESH_Mesh*        aMesh,
-                                                            const TopoDS_Edge& theEdge,
-                                                            const TopoDS_Edge& fromEdge)
+pair<int,TopoDS_Edge>
+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 ));
   }
   
index 53064e7f14028e7f1e6238bc567397e34a2cccaa..ca57f556a191679304132a44802f018cc0a2c123 100644 (file)
@@ -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<int,TopoDS_Edge> - propagation step and found edge
    */
-  static TopoDS_Edge GetPropagationEdge( SMESH_Mesh*        aMesh,
-                                         const TopoDS_Edge& anEdge,
-                                         const TopoDS_Edge& fromEdge);
+  static std::pair<int,TopoDS_Edge> GetPropagationEdge( SMESH_Mesh*        aMesh,
+                                                        const TopoDS_Edge& anEdge,
+                                                        const TopoDS_Edge& fromEdge);
 
   /*!
    * \brief Find corresponding nodes on two faces
index 1bfdc41c5a3db5df1be7bbeb0f09afcc6b4584c5..d3d2925756f4be27b5e547990283f57406f79f72 100644 (file)
@@ -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 
index 4aa83bdd0c30c2482d9e7385284911119602d00b..687ccc4af384b7661b55141d3fcc837413ec5547 100644 (file)
@@ -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;
 }
index 68eda5d6593ea297364697efd0f8b1d9b276a54b..4a3d9a63070b61c2662bd4aacfcfce09efa7a199 100644 (file)
@@ -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 SMESHDS_Hypothesis * >::const_iterator itl;
 
   const list <const SMESHDS_Hypothesis * >&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() );
index 9bbab440ec897f38f19a76b497fd3e55cbc9a31c..306ae1830b11493e3cf31c72aba4964bdc1c2815 100644 (file)
 
 #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 <TopTools_MapOfShape.hxx>
+#include <TopTools_ListIteratorOfListOfShape.hxx>
+#include <BRepTools_WireExplorer.hxx>
+
+#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<SMESH_subMesh*>::const_iterator from,
+                                    list<SMESH_subMesh*>::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 <theMainEdge>
-//     list<SMESH_subMesh*> & 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 <anE>
-//         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<SMESH_subMesh*> & chain = chainData->mySubMeshes;
+    chain.clear();
+    chain.push_back( theMainSubMesh );
+
+    TopTools_MapOfShape checkedShapes;
+    checkedShapes.Add( theMainEdge );
+
+    list<SMESH_subMesh*>::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 <anE>
+      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<TopoDS_Edge> 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<PropagationMgrData*>( 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<SMESH_subMesh*> sourceSM = data->mySubMeshes;
+        clearPropagationChain( subMesh );
+        SMESH_subMeshIteratorPtr smIt = iterate( sourceSM.begin(), sourceSM.end());
+        while ( smIt->more() )
+          buildPropagationChain( smIt->next() );
+      }
       return;
     }
     } // switch by SubMeshState
   }
+
 } // namespace
index c0d2f3cdf8a920837b5c3874e2d13ffe3098aee7..62ad2a439db3b2c552ee453e12ad02c09746ec66 100644 (file)
@@ -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
index b16eeb58e41bdec8eb8d38a2d167597121233c8f..3e04aa8723ef9338abbe9438fb01a38f99843b56 100644 (file)
@@ -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
 }
 
 //=============================================================================
index 8a16594023e981506d8590d6d35c411e73d6ec71..2c3c741286e41e01d8b0b1016213a8fb3a8fd6c1 100644 (file)
@@ -119,7 +119,7 @@ bool StdMeshers_Quadrangle_2D::CheckHypothesis
   aStatus = SMESH_Hypothesis::HYP_OK;
 
   // there is only one compatible Hypothesis so far
-  const list <const SMESHDS_Hypothesis * >&hyps = GetUsedHypothesis(aMesh, aShape);
+  const list <const SMESHDS_Hypothesis * >&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<UVPtStruct>& uv_e2 = quad->side[2]->GetUVPtStruct(true,1 );
   const vector<UVPtStruct>& 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<UVPtStruct>& 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;
index 90db88e55f9048b743f5b4622159fed33544be4c..72b317be290a185a86f41ec699365858fbe68629 100644 (file)
@@ -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,
index c83bff5250a62d5bf73eee982f1b4d511d9f5b41..128b32077354caca976777bf214dc0ac52f87489 100644 (file)
@@ -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")<<nbShells);
+    return error(COMPERR_BAD_SHAPE, SMESH_Comment("Must be 2 shells but not ")<<nbShells);
 
   // ----------------------------------
   // Associate subshapes of the shells
@@ -192,7 +193,7 @@ bool StdMeshers_RadialPrism_3D::Compute(SMESH_Mesh& aMesh, const TopoDS_Shape& a
     TopoDS_Face outFace = TopoDS::Face( exp.Current() );
     TopoDS_Face inFace;
     if ( !shape2ShapeMap.IsBound( outFace )) {
-      return error(dfltErr(),SMESH_Comment("Corresponding inner face not found for face #" )
+      return error(SMESH_Comment("Corresponding inner face not found for face #" )
                    << meshDS->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() );
index 9e59aa0c6b4a28c654a274a61fd9dee4265ad322..ba5f7450329801135cf9f6445fe72c57eeb9b95c 100644 (file)
@@ -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<double>::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 <aMainEdge> on this edge;
       // get non-auxiliary assigned to _mainEdge
index 7537e621b041a6c543d889abe4a406a06496a3f8..ed77aaf61b21284e99c5df0680737f7de390ad5c 100644 (file)
  */
 //================================================================================
 
-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(...) {
   }
index cc8d7d80187d79ce4d37e85316ac6906d53475f0..6c6d5f68073df578c5e08dd0ff790ea44bc05f73 100644 (file)
@@ -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;
index 02bb83a356cdcb578b31c91ef7f67121d99f86db..f5468b118c6d13995b8fde295f45d8d9f496f788 100644 (file)
@@ -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();
index 1be50e5d19a41676b2a34cd10245a54e5c407f80..cfa7002360e423c662f21c380b0ab66e813564c6 100644 (file)
@@ -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" )
   {