Salome HOME
Merge branch 'V8_3_BR' into V8_4_BR V8_4_BR
authorvsr <vsr@opencascade.com>
Fri, 30 Mar 2018 14:20:40 +0000 (17:20 +0300)
committervsr <vsr@opencascade.com>
Fri, 30 Mar 2018 14:20:40 +0000 (17:20 +0300)
149 files changed:
CMakeLists.txt
ChangeLog
README
SalomeSMESHConfig.cmake.in
doc/salome/examples/CMakeLists.txt
doc/salome/examples/CTestTestfileInstall.cmake
doc/salome/examples/create_penta_biquad.py [new file with mode: 0644]
doc/salome/examples/extrusion_penta_biquad.py [new file with mode: 0644]
doc/salome/examples/modifying_meshes_ex22.py
doc/salome/examples/tests.set [new file with mode: 0644]
doc/salome/gui/SMESH/doxyfile.in
doc/salome/gui/SMESH/doxyfile_py.in
doc/salome/gui/SMESH/images/prism_mesh.png [new file with mode: 0644]
doc/salome/gui/SMESH/input/constructing_meshes.doc
doc/salome/gui/SMESH/input/prism_3d_algo.doc
doc/salome/gui/SMESH/input/smeshpy_interface.doc
idl/SMESH_Gen.idl
idl/SMESH_Mesh.idl
src/Controls/SMESH_Controls.cxx
src/Controls/SMESH_ControlsDef.hxx
src/DriverCGNS/DriverCGNS_Write.cxx
src/DriverCGNS/DriverCGNS_Write.hxx
src/DriverMED/DriverMED_R_SMESHDS_Mesh.cxx
src/DriverMED/DriverMED_W_Field.cxx
src/DriverMED/DriverMED_W_SMESHDS_Mesh.cxx
src/MEDWrapper/Base/MED_Common.hxx
src/MEDWrapper/Base/MED_TStructures.hxx
src/MEDWrapper/Base/MED_Utilities.cxx
src/MEDWrapper/Factory/MED_Factory.cxx
src/MEDWrapper/Factory/MED_Factory.hxx
src/MEDWrapper/V2_2/MED_V2_2_Wrapper.cxx
src/MEDWrapper/V2_2/MED_V2_2_Wrapper.hxx
src/OBJECT/SMESH_Actor.cxx
src/OBJECT/SMESH_DeviceActor.cxx
src/OBJECT/SMESH_ScalarBarActor.cxx
src/OBJECT/SMESH_ScalarBarActor.h
src/SMDS/ObjectPool.hxx
src/SMDS/SMDSAbs_ElementType.hxx
src/SMDS/SMDS_Downward.cxx
src/SMDS/SMDS_Mesh.cxx
src/SMDS/SMDS_Mesh.hxx
src/SMDS/SMDS_MeshCell.cxx
src/SMDS/SMDS_MeshGroup.cxx
src/SMDS/SMDS_MeshInfo.hxx
src/SMDS/SMDS_QuadraticVolumeOfNodes.cxx
src/SMDS/SMDS_VtkCellIterator.cxx
src/SMDS/SMDS_VtkVolume.cxx
src/SMESH/SMESH_Algo.cxx
src/SMESH/SMESH_Algo.hxx
src/SMESH/SMESH_Mesh.cxx
src/SMESH/SMESH_Mesh.hxx
src/SMESH/SMESH_MeshEditor.cxx
src/SMESH/SMESH_MesherHelper.cxx
src/SMESH/SMESH_Pattern.cxx
src/SMESH/SMESH_subMesh.cxx
src/SMESHDS/SMESHDS_Command.cxx
src/SMESHDS/SMESHDS_Command.hxx
src/SMESHDS/SMESHDS_CommandType.hxx
src/SMESHDS/SMESHDS_GroupBase.cxx
src/SMESHDS/SMESHDS_GroupBase.hxx
src/SMESHDS/SMESHDS_Mesh.cxx
src/SMESHDS/SMESHDS_Mesh.hxx
src/SMESHDS/SMESHDS_Script.cxx
src/SMESHDS/SMESHDS_Script.hxx
src/SMESHGUI/SMESHGUI.cxx
src/SMESHGUI/SMESHGUI_AddQuadraticElementDlg.cxx
src/SMESHGUI/SMESHGUI_ComputeDlg.cxx
src/SMESHGUI/SMESHGUI_ConvToQuadOp.cxx
src/SMESHGUI/SMESHGUI_DisplayEntitiesDlg.cxx
src/SMESHGUI/SMESHGUI_FieldSelectorWdg.cxx
src/SMESHGUI/SMESHGUI_FieldSelectorWdg.h
src/SMESHGUI/SMESHGUI_Filter.cxx
src/SMESHGUI/SMESHGUI_Filter.h
src/SMESHGUI/SMESHGUI_FilterDlg.cxx
src/SMESHGUI/SMESHGUI_GroupDlg.cxx
src/SMESHGUI/SMESHGUI_GroupOnShapeDlg.cxx
src/SMESHGUI/SMESHGUI_HypothesesUtils.cxx
src/SMESHGUI/SMESHGUI_MeshEditPreview.cxx
src/SMESHGUI/SMESHGUI_MeshInfo.cxx
src/SMESHGUI/SMESHGUI_MeshInfosBox.cxx
src/SMESHGUI/SMESHGUI_MeshInfosBox.h
src/SMESHGUI/SMESHGUI_MultiEditDlg.cxx
src/SMESHGUI/SMESHGUI_Operations.h
src/SMESHGUI/SMESHGUI_Utils.cxx
src/SMESHGUI/SMESH_images.ts
src/SMESHGUI/SMESH_msg_en.ts
src/SMESHGUI/SMESH_msg_fr.ts
src/SMESHGUI/SMESH_msg_ja.ts
src/SMESHUtils/CMakeLists.txt
src/SMESHUtils/SMESH_Delaunay.cxx [new file with mode: 0644]
src/SMESHUtils/SMESH_Delaunay.hxx [new file with mode: 0644]
src/SMESHUtils/SMESH_MeshAlgos.cxx
src/SMESHUtils/SMESH_TryCatch.hxx
src/SMESH_I/SMESH_2smeshpy.cxx
src/SMESH_I/SMESH_2smeshpy.hxx
src/SMESH_I/SMESH_DumpPython.cxx
src/SMESH_I/SMESH_Filter_i.cxx
src/SMESH_I/SMESH_Gen_i.cxx
src/SMESH_I/SMESH_Group_i.cxx
src/SMESH_I/SMESH_MeshEditor_i.cxx
src/SMESH_I/SMESH_Mesh_i.cxx
src/SMESH_I/SMESH_Mesh_i.hxx
src/SMESH_I/SMESH_Pattern_i.cxx
src/SMESH_SWIG/CMakeLists.txt
src/SMESH_SWIG/batchmode_mefisto.py [deleted file]
src/SMESH_SWIG/batchmode_smesh.py [deleted file]
src/SMESH_SWIG/ex29_refine.py
src/SMESH_SWIG/smeshBuilder.py
src/SMESH_SWIG_WITHIHM/CMakeLists.txt
src/SMESH_SWIG_WITHIHM/libSMESH_Swig.cxx
src/SMESH_SWIG_WITHIHM/libSMESH_Swig.h
src/SMESH_SWIG_WITHIHM/libSMESH_Swig.i
src/StdMeshers/StdMeshers_CartesianParameters3D.cxx
src/StdMeshers/StdMeshers_Cartesian_3D.cxx
src/StdMeshers/StdMeshers_Distribution.cxx
src/StdMeshers/StdMeshers_FaceSide.cxx
src/StdMeshers/StdMeshers_FaceSide.hxx
src/StdMeshers/StdMeshers_Hexa_3D.hxx
src/StdMeshers/StdMeshers_Import_1D2D.cxx
src/StdMeshers/StdMeshers_NumberOfSegments.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_2D.cxx
src/StdMeshers/StdMeshers_Projection_3D.hxx
src/StdMeshers/StdMeshers_QuadFromMedialAxis_1D2D.hxx
src/StdMeshers/StdMeshers_Quadrangle_2D.cxx
src/StdMeshers/StdMeshers_Quadrangle_2D.hxx
src/StdMeshers/StdMeshers_RadialPrism_3D.cxx
src/StdMeshers/StdMeshers_RadialPrism_3D.hxx
src/StdMeshers/StdMeshers_RadialQuadrangle_1D2D.cxx
src/StdMeshers/StdMeshers_RadialQuadrangle_1D2D.hxx
src/StdMeshers/StdMeshers_Regular_1D.cxx
src/StdMeshers/StdMeshers_ViscousLayers.cxx
src/StdMeshers/StdMeshers_ViscousLayers2D.cxx
src/StdMeshersGUI/StdMeshersGUI_DistrPreview.cxx
src/Tools/MGCleanerPlug/CMakeLists.txt
src/Tools/MeshCut/CMakeLists.txt
src/Tools/Verima/Gui/CMakeLists.txt
src/Tools/Verima/Stats/Type_Maille.py
src/Tools/YamsPlug/CMakeLists.txt
src/Tools/YamsPlug/doc/Advanced_params.rst
src/Tools/YamsPlug/doc/Mandatory_params.rst
src/Tools/ZCracksPlug/CMakeLists.txt
src/Tools/ZCracksPlug/zcracks.ui
src/Tools/blocFissure/ihm/CMakeLists.txt
src/Tools/padder/meshjob/impl/MeshJobManager_i.cxx
src/Tools/padder/spadderpy/gui/CMakeLists.txt

index ef42ec11a15c27be58e43f59c1df56dc18f78d42..57381c39c65a759d3fd0a9c43f38c2d6e0116936 100755 (executable)
@@ -31,7 +31,7 @@ ENDIF(WIN32)
 STRING(TOUPPER ${PROJECT_NAME} PROJECT_NAME_UC)
 
 SET(${PROJECT_NAME_UC}_MAJOR_VERSION 8)
-SET(${PROJECT_NAME_UC}_MINOR_VERSION 3)
+SET(${PROJECT_NAME_UC}_MINOR_VERSION 4)
 SET(${PROJECT_NAME_UC}_PATCH_VERSION 0)
 SET(${PROJECT_NAME_UC}_VERSION
   ${${PROJECT_NAME_UC}_MAJOR_VERSION}.${${PROJECT_NAME_UC}_MINOR_VERSION}.${${PROJECT_NAME_UC}_PATCH_VERSION})
@@ -77,6 +77,11 @@ OPTION(SALOME_BUILD_DOC "Generate SALOME SMESH documentation" ON)
 OPTION(SALOME_BUILD_GUI            "Enable GUI" ON)
 OPTION(SALOME_SMESH_USE_CGNS       "Enable import/export to CGNS format" OFF)
 OPTION(SALOME_SMESH_USE_TBB        "Enable parallel computation" OFF)
+OPTION(SALOME_SMESH_DYNLOAD_LOCAL  "Load plug-ins' symbols locally (Linux only)" ON)
+
+IF(SALOME_SMESH_DYNLOAD_LOCAL)
+  ADD_DEFINITIONS(-DDYNLOAD_LOCAL)
+ENDIF(SALOME_SMESH_DYNLOAD_LOCAL)
 
 #On Linux use Fortran to compile MEFISTO2D
 IF(NOT WIN32)
@@ -85,12 +90,12 @@ IF(NOT WIN32)
   ADD_DEFINITIONS(-DENABLE_MEFISTO)
 ENDIF(NOT WIN32)
 
-MARK_AS_ADVANCED(SALOME_BUILD_GUI SALOME_SMESH_USE_CGNS SALOME_SMESH_USE_TBB)
+MARK_AS_ADVANCED(SALOME_BUILD_GUI SALOME_SMESH_USE_CGNS SALOME_SMESH_USE_TBB SALOME_SMESH_DYNLOAD_LOCAL)
 
 # Prerequisites
 # =============
 # Find "big" prerequisites first - they reference themselves many others
-#   -> this can help finding the smaller prerequisites and detect conficts.
+#   -> this can help finding the smaller prerequisites and detect conflicts.
 # In our case KERNEL has already loaded many prereq:
 
 ##
index 85c700e46b384a279d31307c83cc98aeaabe0951..7df59af50485b12d386e4fc3d2978ecbedba5a32 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -37,7 +37,7 @@
 
 2004-01-05 16:14  Jerome Robert <jerome.robert@eads.net>
 
-       * adm_local/unix/config_files/check_Netgen.m4: Fix a mispelled
+       * adm_local/unix/config_files/check_Netgen.m4: Fix a misspelled
          environment variable for idl python
 
 2004-01-05 14:28  tag V1_3_1
@@ -59,7 +59,7 @@
 2004-01-05 09:05  Jerome Robert <jerome.robert@eads.net>
 
        * src/: SMDS/SMDS_Mesh.cxx, SMESHDS/SMESHDS_Document.cxx: [Bug
-         SMESH4830] bug in instal with gcc 2.95. Bug fixed.  Note: SGI say
+         SMESH4830] bug in install with gcc 2.95. Bug fixed.  Note: SGI say
          that <algorithm> is requiered to use set_intersection (see
          http://www.sgi.com/tech/stl/set_intersection.html).
 
@@ -73,7 +73,7 @@
 2003-12-15 13:15  Nadir Bouhamou <nadir.bouhamou@cea.fr>
 
        * src/SMESHDS/SMESHDS_Script.cxx: correct a small bug found by the
-         EDF developpement team (PN and AT) : AddVolume in the case of a
+         EDF development team (PN and AT) : AddVolume in the case of a
          Tetrahedron.
 
 2003-12-11 09:51  Jerome Robert <jerome.robert@eads.net>
 
        * idl/Makefile.in, adm_local/unix/make_commence.in,
          adm_local/unix/make_omniorb.in, build_configure,
-         configure.in.base: NRI : Update IDL Dependancies.
+         configure.in.base: NRI : Update IDL Dependencies.
 
 2003-05-28 07:20  Nicolas Rejneri <nicolas.rejneri@opencascade.com>
 
diff --git a/README b/README
index 78f5c9b6f48cc85668545b3f5155e597d463d9cf..74932ecbadce56251a3fb5536ca5225cc8a9fab9 100644 (file)
--- a/README
+++ b/README
@@ -41,7 +41,7 @@ Installation
 Pre-requisites
 --------------
 
-SALOME platform relies on a set of third-party softwares; some of them are needed
+SALOME platform relies on a set of third-party software; some of them are needed
 at build time only, while other ones are needed in runtime also.
 
 For more information about the pre-requisites please visit SALOME platform web
index 6fe86346c53f50c6ce095014790dfdd9fe25e44d..7ff429caf41dff8191ddc3a50e380dc6499ed54d 100644 (file)
@@ -1,6 +1,6 @@
 # - Config file for the @PROJECT_NAME@ package
 # It defines the following variables. 
-# Specific to the pacakge @PROJECT_NAME@ itself:
+# Specific to the package @PROJECT_NAME@ itself:
 #  @PROJECT_NAME_UC@_ROOT_DIR_EXP - the root path of the installation providing this CMake file
 #
 
index 552a9d1b2d2f6684a87c961a83e414fd3886bb11..01ed3f5aca924bcc614c9f3bae08b6fadd23afc3 100644 (file)
@@ -1,4 +1,4 @@
-# Copyright (C) 2012-2016  CEA/DEN, EDF R&D, OPEN CASCADE
+# Copyright (C) 2012-2017  CEA/DEN, EDF R&D, OPEN CASCADE
 #
 # This library is free software; you can redistribute it and/or
 # modify it under the terms of the GNU Lesser General Public
 # See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 #
 
-# examples that can't be used for testing because they use external mesher plug-ins
-SET(BAD_TESTS
-  3dmesh.py
-  a3DmeshOnModified2Dmesh.py
-  creating_meshes_ex01.py
-  creating_meshes_ex03.py
-  creating_meshes_ex05.py
-  defining_hypotheses_ex06.py
-  defining_hypotheses_ex09.py
-  defining_hypotheses_ex17.py
-  filters_ex02.py
-  filters_ex08.py
-  filters_ex23.py
-  filters_ex24.py
-  filters_ex25.py
-  filters_ex32.py
-  filters_ex35.py
-  generate_flat_elements.py
-  modifying_meshes_ex26.py
-  notebook_smesh.py
-  quality_controls_ex06.py
-  quality_controls_ex20.py
-  quality_controls_ex21.py
-  quality_controls_ex22.py
-  viewing_meshes_ex01.py
-  )
-
-SET(GOOD_TESTS
-  cartesian_algo.py
-  creating_meshes_ex02.py
-  creating_meshes_ex04.py
-  creating_meshes_ex06.py
-  creating_meshes_ex07.py
-  creating_meshes_ex08.py
-  defining_hypotheses_ex01.py
-  defining_hypotheses_ex02.py
-  defining_hypotheses_ex03.py
-  defining_hypotheses_ex04.py
-  defining_hypotheses_ex05.py
-  defining_hypotheses_ex07.py
-  defining_hypotheses_ex08.py
-  defining_hypotheses_ex10.py
-  defining_hypotheses_ex11.py
-  defining_hypotheses_ex12.py
-  defining_hypotheses_ex13.py
-  defining_hypotheses_ex14.py
-  defining_hypotheses_ex15.py
-  defining_hypotheses_ex16.py
-  defining_hypotheses_adaptive1d.py
-  filters_ex01.py
-  filters_ex03.py
-  filters_ex04.py
-  filters_ex05.py
-  filters_ex06.py
-  filters_ex07.py
-  filters_ex09.py
-  filters_ex10.py
-  filters_ex11.py
-  filters_ex12.py
-  filters_ex13.py
-  filters_ex14.py
-  filters_ex15.py
-  filters_ex16.py
-  filters_ex17.py
-  filters_ex18.py
-  filters_ex19.py
-  filters_ex20.py
-  filters_ex21.py
-  filters_ex22.py
-  filters_ex26.py
-  filters_ex27.py
-  filters_ex28.py
-  filters_ex29.py
-  filters_ex30.py
-  filters_ex31.py
-  filters_ex33.py
-  filters_ex34.py
-  filters_ex36.py
-  filters_ex37.py
-  filters_ex38.py
-  filters_ex39.py
-  filters_node_nb_conn.py
-  filters_belong2group.py
-  grouping_elements_ex01.py
-  grouping_elements_ex02.py
-  grouping_elements_ex03.py
-  grouping_elements_ex04.py
-  grouping_elements_ex05.py
-  grouping_elements_ex06.py
-  grouping_elements_ex07.py
-  grouping_elements_ex08.py
-  measurements_ex01.py
-  measurements_ex02.py
-  modifying_meshes_ex01.py
-  modifying_meshes_ex02.py
-  modifying_meshes_ex03.py
-  modifying_meshes_ex04.py
-  modifying_meshes_ex05.py
-  modifying_meshes_ex06.py
-  modifying_meshes_ex07.py
-  modifying_meshes_ex08.py
-  modifying_meshes_ex09.py
-  modifying_meshes_ex10.py
-  modifying_meshes_ex11.py
-  modifying_meshes_ex12.py
-  modifying_meshes_ex13.py
-  modifying_meshes_ex14.py
-  modifying_meshes_ex15.py
-  modifying_meshes_ex16.py
-  modifying_meshes_ex17.py
-  modifying_meshes_ex18.py
-  modifying_meshes_ex19.py
-  modifying_meshes_ex20.py
-  modifying_meshes_ex21.py
-  modifying_meshes_ex22.py
-  modifying_meshes_ex23.py
-  modifying_meshes_ex24.py
-  modifying_meshes_ex25.py
-  prism_3d_algo.py
-  quality_controls_ex01.py
-  quality_controls_ex02.py
-  quality_controls_ex03.py
-  quality_controls_ex04.py
-  quality_controls_ex05.py
-  quality_controls_ex07.py
-  quality_controls_ex08.py
-  quality_controls_ex09.py
-  quality_controls_ex10.py
-  quality_controls_ex11.py
-  quality_controls_ex12.py
-  quality_controls_ex13.py
-  quality_controls_ex14.py
-  quality_controls_ex15.py
-  quality_controls_ex16.py
-  quality_controls_ex17.py
-  quality_controls_ex18.py
-  quality_controls_ex19.py
-  transforming_meshes_ex01.py
-  transforming_meshes_ex02.py
-  transforming_meshes_ex03.py
-  transforming_meshes_ex04.py
-  transforming_meshes_ex05.py
-  transforming_meshes_ex06.py
-  transforming_meshes_ex07.py
-  transforming_meshes_ex08.py
-  transforming_meshes_ex09.py
-  transforming_meshes_ex10.py
-  transforming_meshes_ex11.py
-  transforming_meshes_ex12.py
-  transforming_meshes_ex13.py
-  use_existing_faces.py
-  viewing_meshes_ex02.py
-  split_biquad.py
-)
-
-SET(EXAMPLES_TESTS ${BAD_TESTS} ${GOOD_TESTS} testme.py)
+INCLUDE(tests.set)
 
 SALOME_GENERATE_TESTS_ENVIRONMENT(tests_env)
 
@@ -194,3 +39,4 @@ INSTALL(FILES ${GOOD_TESTS} DESTINATION ${TEST_INSTALL_DIRECTORY})
 INSTALL(FILES CTestTestfileInstall.cmake
         DESTINATION ${TEST_INSTALL_DIRECTORY}
         RENAME CTestTestfile.cmake)
+INSTALL(FILES tests.set DESTINATION ${TEST_INSTALL_DIRECTORY})
index d56f4206547f05f41cef0d90bba4afee19e04a47..c44ec0c5738b30c701bd412a612b7ac9ce1f35e8 100644 (file)
@@ -1,4 +1,4 @@
-# Copyright (C) 2015-2016  CEA/DEN, EDF R&D, OPEN CASCADE
+# Copyright (C) 2015-2017  CEA/DEN, EDF R&D, OPEN CASCADE
 #
 # This library is free software; you can redistribute it and/or
 # modify it under the terms of the GNU Lesser General Public
 # See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 #
 
+INCLUDE(tests.set)
+
 SET(SALOME_TEST_DRIVER "$ENV{ABSOLUTE_APPLI_PATH}/bin/salome/appliskel/salome_test_driver.py")
 SET(COMPONENT_NAME SMESH)
 SET(TIMEOUT        300)
 
-SET(GOOD_TESTS
-  cartesian_algo
-  creating_meshes_ex02
-  creating_meshes_ex04
-  creating_meshes_ex06
-  creating_meshes_ex07
-  creating_meshes_ex08
-  defining_hypotheses_ex01
-  defining_hypotheses_ex02
-  defining_hypotheses_ex03
-  defining_hypotheses_ex04
-  defining_hypotheses_ex05
-  defining_hypotheses_ex07
-  defining_hypotheses_ex08
-  defining_hypotheses_ex10
-  defining_hypotheses_ex11
-  defining_hypotheses_ex12
-  defining_hypotheses_ex13
-  defining_hypotheses_ex14
-  defining_hypotheses_ex15
-  defining_hypotheses_ex16
-  defining_hypotheses_adaptive1d
-  filters_ex01
-  filters_ex03
-  filters_ex04
-  filters_ex05
-  filters_ex06
-  filters_ex07
-  filters_ex09
-  filters_ex10
-  filters_ex11
-  filters_ex12
-  filters_ex13
-  filters_ex14
-  filters_ex15
-  filters_ex16
-  filters_ex17
-  filters_ex18
-  filters_ex19
-  filters_ex20
-  filters_ex21
-  filters_ex22
-  filters_ex26
-  filters_ex27
-  filters_ex28
-  filters_ex29
-  filters_ex30
-  filters_ex31
-  filters_ex33
-  filters_ex34
-  filters_ex36
-  grouping_elements_ex01
-  grouping_elements_ex02
-  grouping_elements_ex03
-  grouping_elements_ex04
-  grouping_elements_ex05
-  grouping_elements_ex06
-  grouping_elements_ex07
-  grouping_elements_ex08
-  measurements_ex01
-  measurements_ex02
-  modifying_meshes_ex01
-  modifying_meshes_ex02
-  modifying_meshes_ex03
-  modifying_meshes_ex04
-  modifying_meshes_ex05
-  modifying_meshes_ex06
-  modifying_meshes_ex07
-  modifying_meshes_ex08
-  modifying_meshes_ex09
-  modifying_meshes_ex10
-  modifying_meshes_ex11
-  modifying_meshes_ex12
-  modifying_meshes_ex13
-  modifying_meshes_ex14
-  modifying_meshes_ex15
-  modifying_meshes_ex16
-  modifying_meshes_ex17
-  modifying_meshes_ex18
-  modifying_meshes_ex19
-  modifying_meshes_ex20
-  modifying_meshes_ex21
-  modifying_meshes_ex22
-  modifying_meshes_ex23
-  modifying_meshes_ex24
-  modifying_meshes_ex25
-  prism_3d_algo
-  quality_controls_ex01
-  quality_controls_ex02
-  quality_controls_ex03
-  quality_controls_ex04
-  quality_controls_ex05
-  quality_controls_ex07
-  quality_controls_ex08
-  quality_controls_ex09
-  quality_controls_ex10
-  quality_controls_ex11
-  quality_controls_ex12
-  quality_controls_ex13
-  quality_controls_ex14
-  quality_controls_ex15
-  quality_controls_ex16
-  quality_controls_ex17
-  quality_controls_ex18
-  quality_controls_ex19
-  transforming_meshes_ex01
-  transforming_meshes_ex02
-  transforming_meshes_ex03
-  transforming_meshes_ex04
-  transforming_meshes_ex05
-  transforming_meshes_ex06
-  transforming_meshes_ex07
-  transforming_meshes_ex08
-  transforming_meshes_ex09
-  transforming_meshes_ex10
-  transforming_meshes_ex11
-  transforming_meshes_ex12
-  transforming_meshes_ex13
-  use_existing_faces
-  viewing_meshes_ex02
-)
-
 FOREACH(tfile ${GOOD_TESTS})
-  SET(TEST_NAME SMESH_${tfile})
-  ADD_TEST(${TEST_NAME} python ${SALOME_TEST_DRIVER} ${TIMEOUT} ${tfile}.py)
+  GET_FILENAME_COMPONENT(BASE_NAME ${tfile} NAME_WE)
+  SET(TEST_NAME SMESH_${BASE_NAME})
+  ADD_TEST(${TEST_NAME} python ${SALOME_TEST_DRIVER} ${TIMEOUT} ${tfile})
   SET_TESTS_PROPERTIES(${TEST_NAME} PROPERTIES LABELS "${COMPONENT_NAME}")
 ENDFOREACH()
diff --git a/doc/salome/examples/create_penta_biquad.py b/doc/salome/examples/create_penta_biquad.py
new file mode 100644 (file)
index 0000000..60b1b61
--- /dev/null
@@ -0,0 +1,43 @@
+# -*- coding: utf-8 -*-
+
+import sys
+import salome
+
+salome.salome_init()
+theStudy = salome.myStudy
+
+import  SMESH, SALOMEDS
+from salome.smesh import smeshBuilder
+
+smesh = smeshBuilder.New(theStudy)
+unPentaBiQuad = smesh.Mesh()
+nodeID = unPentaBiQuad.AddNode( 0, 0, 0 )
+nodeID = unPentaBiQuad.AddNode( 10, 0, 0 )
+nodeID = unPentaBiQuad.AddNode( 0, 10, 0 )
+nodeID = unPentaBiQuad.AddNode( 0, 0, 10 )
+nodeID = unPentaBiQuad.AddNode( 10, 0, 10 )
+nodeID = unPentaBiQuad.AddNode( 0, 10, 10 )
+nodeID = unPentaBiQuad.AddNode( 5, 0, 0 )
+nodeID = unPentaBiQuad.AddNode( 7, 7, 0 )
+nodeID = unPentaBiQuad.AddNode( 0, 5, 0 )
+nodeID = unPentaBiQuad.AddNode( 5, 0, 10 )
+nodeID = unPentaBiQuad.AddNode( 7, 7, 10 )
+nodeID = unPentaBiQuad.AddNode( 0, 5, 10 )
+nodeID = unPentaBiQuad.AddNode( 0, 0, 5 )
+nodeID = unPentaBiQuad.AddNode( 10, 0, 5 )
+nodeID = unPentaBiQuad.AddNode( 0, 10, 5 )
+nodeID = unPentaBiQuad.AddNode( 5, -1, 5 )
+nodeID = unPentaBiQuad.AddNode( 8, 8, 5 )
+nodeID = unPentaBiQuad.AddNode( -1, 5, 5 )
+volID = unPentaBiQuad.AddVolume( [ 4, 5, 6, 1, 2, 3, 10, 11, 12, 7, 8, 9, 13, 14, 15, 16, 17, 18 ] )
+
+infos = unPentaBiQuad.GetMeshInfo()
+print "Number of biquadratic pentahedrons:", infos[SMESH.Entity_BiQuad_Penta]
+if (infos[SMESH.Entity_BiQuad_Penta] != 1):
+  raise RuntimeError("Bad number of biquadratic pentahedrons: should be 1")
+
+## Set names of Mesh objects
+smesh.SetName(unPentaBiQuad.GetMesh(), 'unPentaBiQuad')
+
+if salome.sg.hasDesktop():
+  salome.sg.updateObjBrowser(True)
diff --git a/doc/salome/examples/extrusion_penta_biquad.py b/doc/salome/examples/extrusion_penta_biquad.py
new file mode 100644 (file)
index 0000000..90cc208
--- /dev/null
@@ -0,0 +1,55 @@
+# -*- coding: utf-8 -*-
+
+import sys
+import salome
+
+salome.salome_init()
+theStudy = salome.myStudy
+
+import GEOM
+from salome.geom import geomBuilder
+import math
+import SALOMEDS
+
+geompy = geomBuilder.New(theStudy)
+
+O = geompy.MakeVertex(0, 0, 0)
+OX = geompy.MakeVectorDXDYDZ(1, 0, 0)
+OY = geompy.MakeVectorDXDYDZ(0, 1, 0)
+OZ = geompy.MakeVectorDXDYDZ(0, 0, 1)
+Divided_Disk_1 = geompy.MakeDividedDisk(100, 1, GEOM.SQUARE)
+geompy.addToStudy( O, 'O' )
+geompy.addToStudy( OX, 'OX' )
+geompy.addToStudy( OY, 'OY' )
+geompy.addToStudy( OZ, 'OZ' )
+geompy.addToStudy( Divided_Disk_1, 'Divided Disk_1' )
+
+import  SMESH, SALOMEDS
+from salome.smesh import smeshBuilder
+
+smesh = smeshBuilder.New(theStudy)
+aFilterManager = smesh.CreateFilterManager()
+Mesh_1 = smesh.Mesh(Divided_Disk_1)
+Regular_1D = Mesh_1.Segment()
+Number_of_Segments_1 = Regular_1D.NumberOfSegments(6)
+Quadrangle_2D = Mesh_1.Quadrangle(algo=smeshBuilder.QUADRANGLE)
+isDone = Mesh_1.Compute()
+aMaxElementLength2D0x5d7fdf0 = aFilterManager.CreateMaxElementLength2D()
+isDone = Mesh_1.QuadToTriObject( Mesh_1,  )
+Mesh_1.ExtrusionSweepObjects( [ Mesh_1 ], [ Mesh_1 ], [ Mesh_1 ], [ 0, 0, 50 ], 3, 1 )
+Mesh_1.ConvertToQuadratic(0, Mesh_1,True)
+
+infos = Mesh_1.GetMeshInfo()
+print "Number of biquadratic pentahedrons:", infos[SMESH.Entity_BiQuad_Penta]
+if (infos[SMESH.Entity_BiQuad_Penta] != 1080):
+  raise RuntimeError("Bad number of biquadratic pentahedrons: should be 1080")
+  
+## Set names of Mesh objects
+smesh.SetName(Regular_1D.GetAlgorithm(), 'Regular_1D')
+smesh.SetName(Quadrangle_2D.GetAlgorithm(), 'Quadrangle_2D')
+smesh.SetName(Number_of_Segments_1, 'Number of Segments_1')
+smesh.SetName(Mesh_1.GetMesh(), 'Mesh_1')
+
+
+if salome.sg.hasDesktop():
+  salome.sg.updateObjBrowser(True)
index b4f5f3cd3da60168d479bb0c0d69d946704358d5..8444ee567faec359ce4814d606da9079ae6d15cf 100644 (file)
@@ -1,34 +1,90 @@
 # Extrusion
 
 
-import salome
+import salome, math
 salome.salome_init()
-import GEOM
 from salome.geom import geomBuilder
 geompy = geomBuilder.New(salome.myStudy)
 
-import SMESH, SALOMEDS
+import SMESH
 from salome.smesh import smeshBuilder
 smesh =  smeshBuilder.New(salome.myStudy)
 
-import SMESH_mechanic
+# create an empty mesh
+mesh = smesh.Mesh() 
 
-#smesh = SMESH_mechanic.smesh
-mesh = SMESH_mechanic.mesh 
+# add a node
+mesh.AddNode( 0.,0.,0. )
 
-# select the top face
-faces = geompy.SubShapeAllSorted(SMESH_mechanic.shape_mesh, geompy.ShapeType["FACE"])
-face = faces[7]
-geompy.addToStudyInFather(SMESH_mechanic.shape_mesh, face, "face circular top")
+# extrude a node into a line of 10 segments along the X axis
+ids = mesh.GetNodesId()
+stepVector = [1.,0.,0.]
+nbSteps = 10
+mesh.ExtrusionSweep( ids, stepVector, nbSteps, IsNodes=True )
 
-# create a vector for extrusion
-point = SMESH.PointStruct(0., 0., 5.)
-vector = SMESH.DirStruct(point)
+# create some groups
+lastNode      = mesh.GetNodesId()[-1]
+lastNodeGroup = mesh.MakeGroupByIds( "node %s"% lastNode, SMESH.NODE, [lastNode])
+lineGroup     = mesh.MakeGroupByIds( "line", SMESH.EDGE, mesh.GetElementsId() )
 
-# create a group to be extruded
-GroupTri = mesh.GroupOnGeom(face, "Group of faces (extrusion)", SMESH.FACE)
+# rotate the segments around the first node to get a mesh of a disk quarter
+axisZ  = [0.,0.,0., 0.,0.,1.]
+groups = mesh.RotationSweepObject( lineGroup, axisZ, math.pi/2., 10, 1e-3, MakeGroups=True, TotalAngle=True )
 
-# perform extrusion of the group
-mesh.ExtrusionSweepObject(GroupTri, vector, 5)
+# extrude all faces into volumes
+obj        = mesh
+stepVector = [0.,0.,-1.]
+nbSteps    = 5
+groups = mesh.ExtrusionSweepObject2D( obj, stepVector, nbSteps, MakeGroups=True )
+
+# remove all segments created by the last command
+for g in groups:
+    if g.GetType() == SMESH.EDGE:
+        mesh.RemoveGroupWithContents( g )
+
+# extrude all segments into faces along Z
+obj = mesh
+stepVector = [0.,0.,1.]
+mesh.ExtrusionSweepObject1D( obj, stepVector, nbSteps )
+
+# extrude a group
+lineExtruded = None
+for g in mesh.GetGroups( SMESH.FACE ):
+    if g.GetName() == "line_extruded":
+        lineExtruded = g
+        break
+obj        = lineExtruded
+stepVector = [0,-5.,0.]
+nbSteps    = 1
+mesh.ExtrusionSweepObject( obj, stepVector, nbSteps )
+
+# extrude all nodes and triangle faces of the disk quarter, applying a scale factor
+diskGroup = None
+for g in mesh.GetGroups( SMESH.FACE ):
+    if g.GetName() == "line_rotated":
+        diskGroup = g
+        break
+crit = [ smesh.GetCriterion( SMESH.FACE, SMESH.FT_ElemGeomType,'=',SMESH.Geom_TRIANGLE ),
+         smesh.GetCriterion( SMESH.FACE, SMESH.FT_BelongToMeshGroup,'=', diskGroup )]
+trianglesFilter = smesh.GetFilterFromCriteria( crit )
+
+nodes      = [ diskGroup ]
+edges      = []
+faces      = [ trianglesFilter ]
+stepVector = [0,0,1]
+nbSteps    = 10
+mesh.ExtrusionSweepObjects( nodes, edges, faces, stepVector, nbSteps, scaleFactors=[0.5], linearVariation=True )
+
+# extrude a cylindrical group of faces by normal
+cylGroup = None
+for g in mesh.GetGroups( SMESH.FACE ):
+    if g.GetName().startswith("node "):
+        cylGroup = g
+        break
+
+elements = cylGroup
+stepSize = 5.
+nbSteps  = 2
+mesh.ExtrusionByNormal( elements, stepSize, nbSteps )
 
 salome.sg.updateObjBrowser(True)
diff --git a/doc/salome/examples/tests.set b/doc/salome/examples/tests.set
new file mode 100644 (file)
index 0000000..3319c32
--- /dev/null
@@ -0,0 +1,177 @@
+# Copyright (C) 2015-2017  CEA/DEN, EDF R&D, OPEN CASCADE
+#
+# 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, or (at your option) any later version.
+#
+# 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
+#
+
+# examples that can't be used for testing because they use external mesher plug-ins
+SET(BAD_TESTS
+  3dmesh.py
+  a3DmeshOnModified2Dmesh.py
+  creating_meshes_ex01.py
+  creating_meshes_ex03.py
+  creating_meshes_ex05.py
+  defining_hypotheses_ex06.py
+  defining_hypotheses_ex09.py
+  defining_hypotheses_ex17.py
+  filters_ex02.py
+  filters_ex08.py
+  filters_ex23.py
+  filters_ex24.py
+  filters_ex25.py
+  filters_ex32.py
+  filters_ex35.py
+  generate_flat_elements.py
+  modifying_meshes_ex26.py
+  notebook_smesh.py
+  quality_controls_ex06.py
+  quality_controls_ex20.py
+  quality_controls_ex21.py
+  quality_controls_ex22.py
+  viewing_meshes_ex01.py
+  )
+
+SET(GOOD_TESTS
+  cartesian_algo.py
+  create_penta_biquad.py
+  creating_meshes_ex02.py
+  creating_meshes_ex04.py
+  creating_meshes_ex06.py
+  creating_meshes_ex07.py
+  creating_meshes_ex08.py
+  defining_hypotheses_ex01.py
+  defining_hypotheses_ex02.py
+  defining_hypotheses_ex03.py
+  defining_hypotheses_ex04.py
+  defining_hypotheses_ex05.py
+  defining_hypotheses_ex07.py
+  defining_hypotheses_ex08.py
+  defining_hypotheses_ex10.py
+  defining_hypotheses_ex11.py
+  defining_hypotheses_ex12.py
+  defining_hypotheses_ex13.py
+  defining_hypotheses_ex14.py
+  defining_hypotheses_ex15.py
+  defining_hypotheses_ex16.py
+  defining_hypotheses_adaptive1d.py
+  extrusion_penta_biquad.py
+  filters_ex01.py
+  filters_ex03.py
+  filters_ex04.py
+  filters_ex05.py
+  filters_ex06.py
+  filters_ex07.py
+  filters_ex09.py
+  filters_ex10.py
+  filters_ex11.py
+  filters_ex12.py
+  filters_ex13.py
+  filters_ex14.py
+  filters_ex15.py
+  filters_ex16.py
+  filters_ex17.py
+  filters_ex18.py
+  filters_ex19.py
+  filters_ex20.py
+  filters_ex21.py
+  filters_ex22.py
+  filters_ex26.py
+  filters_ex27.py
+  filters_ex28.py
+  filters_ex29.py
+  filters_ex30.py
+  filters_ex31.py
+  filters_ex33.py
+  filters_ex34.py
+  filters_ex36.py
+  filters_ex37.py
+  filters_ex38.py
+  filters_ex39.py
+  filters_node_nb_conn.py
+  filters_belong2group.py
+  grouping_elements_ex01.py
+  grouping_elements_ex02.py
+  grouping_elements_ex03.py
+  grouping_elements_ex04.py
+  grouping_elements_ex05.py
+  grouping_elements_ex06.py
+  grouping_elements_ex07.py
+  grouping_elements_ex08.py
+  measurements_ex01.py
+  measurements_ex02.py
+  modifying_meshes_ex01.py
+  modifying_meshes_ex02.py
+  modifying_meshes_ex03.py
+  modifying_meshes_ex04.py
+  modifying_meshes_ex05.py
+  modifying_meshes_ex06.py
+  modifying_meshes_ex07.py
+  modifying_meshes_ex08.py
+  modifying_meshes_ex09.py
+  modifying_meshes_ex10.py
+  modifying_meshes_ex11.py
+  modifying_meshes_ex12.py
+  modifying_meshes_ex13.py
+  modifying_meshes_ex14.py
+  modifying_meshes_ex15.py
+  modifying_meshes_ex16.py
+  modifying_meshes_ex17.py
+  modifying_meshes_ex18.py
+  modifying_meshes_ex19.py
+  modifying_meshes_ex20.py
+  modifying_meshes_ex21.py
+  modifying_meshes_ex22.py
+  modifying_meshes_ex23.py
+  modifying_meshes_ex24.py
+  modifying_meshes_ex25.py
+  prism_3d_algo.py
+  quality_controls_ex01.py
+  quality_controls_ex02.py
+  quality_controls_ex03.py
+  quality_controls_ex04.py
+  quality_controls_ex05.py
+  quality_controls_ex07.py
+  quality_controls_ex08.py
+  quality_controls_ex09.py
+  quality_controls_ex10.py
+  quality_controls_ex11.py
+  quality_controls_ex12.py
+  quality_controls_ex13.py
+  quality_controls_ex14.py
+  quality_controls_ex15.py
+  quality_controls_ex16.py
+  quality_controls_ex17.py
+  quality_controls_ex18.py
+  quality_controls_ex19.py
+  transforming_meshes_ex01.py
+  transforming_meshes_ex02.py
+  transforming_meshes_ex03.py
+  transforming_meshes_ex04.py
+  transforming_meshes_ex05.py
+  transforming_meshes_ex06.py
+  transforming_meshes_ex07.py
+  transforming_meshes_ex08.py
+  transforming_meshes_ex09.py
+  transforming_meshes_ex10.py
+  transforming_meshes_ex11.py
+  transforming_meshes_ex12.py
+  transforming_meshes_ex13.py
+  use_existing_faces.py
+  viewing_meshes_ex02.py
+  split_biquad.py
+)
+
+SET(EXAMPLES_TESTS ${BAD_TESTS} ${GOOD_TESTS} testme.py)
index 164ad922093500e386e7853652c3e709d4624132..2b716b2c0feca923420ff7f5a4c51ea42bbe17d0 100755 (executable)
@@ -41,6 +41,7 @@ WARNINGS          = YES
 INPUT             = @CMAKE_CURRENT_SOURCE_DIR@/input $(GEOM_ROOT_DIR)/share/doc/salome/gui/GEOM/input
 FILE_PATTERNS     = *.doc
 EXCLUDE           = 
+EXCLUDE_PATTERNS  = tui_*.doc
 IMAGE_PATH        = $(GEOM_ROOT_DIR)/share/doc/salome/gui/GEOM @CMAKE_CURRENT_SOURCE_DIR@/images
 EXAMPLE_PATH      = @CMAKE_SOURCE_DIR@/doc/salome/examples @CMAKE_SOURCE_DIR@/src/SMESH_SWIG
 
index d48007ab2988b9beab705ed9ebfcf09f62ca18d6..50b8dbe3e5ef7c9f9c38fcd024846a74892c3108 100755 (executable)
@@ -103,11 +103,12 @@ INPUT             = tmp2/smeshBuilder.py \
                     tmp2/smesh_algorithm.py \
                     tmp2/StdMeshersBuilder.py \
                     tmp2/smeshstudytools.py \
-                    tmp1/smeshBuilder.py
-FILE_PATTERNS     = 
+                    tmp1/smeshBuilder.py \
+                    @CMAKE_CURRENT_SOURCE_DIR@/input
+FILE_PATTERNS     = tui_*.doc
 IMAGE_PATH        = @CMAKE_CURRENT_SOURCE_DIR@/images
 RECURSIVE         = NO
-EXAMPLE_PATH      = @CMAKE_SOURCE_DIR@/src/SMESH_SWIG
+EXAMPLE_PATH      = @CMAKE_SOURCE_DIR@/src/SMESH_SWIG @CMAKE_SOURCE_DIR@/doc/salome/examples
 
 #---------------------------------------------------------------------------
 #HTML related options
@@ -165,3 +166,8 @@ DOT_CLEANUP            = YES
 #---------------------------------------------------------------------------
 GENERATE_TAGFILE  = smeshpy_doc.tag
 SEARCHENGINE           = YES
+
+#---------------------------------------------------------------------------
+#Custom commands
+#---------------------------------------------------------------------------
+ALIASES += tui_script{1}="\include \1 <a href=\"../../examples/SMESH/\1\">Download this script</a>"
diff --git a/doc/salome/gui/SMESH/images/prism_mesh.png b/doc/salome/gui/SMESH/images/prism_mesh.png
new file mode 100644 (file)
index 0000000..95a3121
Binary files /dev/null and b/doc/salome/gui/SMESH/images/prism_mesh.png differ
index 6794b398bea21a50f333c7a54e881af35a9223a5..2481807fd0888fdda36ee1c0c880f28b4a8cb8c0 100644 (file)
@@ -19,7 +19,7 @@ and hypotheses.
 
 Mesh generation on the geometry is performed in the bottom-up
 flow: nodes on vertices are created first, then edges are divided into
-segments using nodes on vertices; the node of segments are then
+segments using nodes on vertices; the nodes of segments are then
 used to mesh faces; then the nodes of faces are used to mesh
 solids. This automatically assures the conformity of the mesh.
 
index 59aee72fa5c19cdb56a4512315a3de867f323f40..6d4be7be89942d9ab1c875301c563827ed834f63 100644 (file)
@@ -6,6 +6,8 @@ Extrusion 3D algorithm can be used for meshing prisms, i.e. 3D shapes
 defined by two opposing faces having the same number of vertices and
 edges. These two faces should be connected by quadrangle "side" faces.
 
+\image html prism_mesh.png "Clipping view of a mesh of a prism with non-planar base and top faces"
+
 The prism is allowed to have sides composed of several faces. (A prism
 side is a row of faces (or one face) connecting the corresponding edges of
 the top and base faces). However, a prism 
index 1dc47c40700a8376a71b6627d82a119e42cafe80..524a4ceb074281232f912b8c8fcfec83ef7b397b 100644 (file)
@@ -2,10 +2,10 @@
 
 \page smeshpy_interface_page Python interface
 
-Python API for SALOME %Mesh module defines several classes that can
+Python API of SALOME %Mesh module defines several classes that can
 be used for easy mesh creation and edition.
 
-Documentation for SALOME %Mesh module Python API is available in two forms:
+Documentation of SALOME %Mesh module Python API is available in two forms:
 - <a href="smeshpy_doc/modules.html">Structured documentation</a>, where all methods and
 classes are grouped by their functionality.
 - <a href="smeshpy_doc/namespaces.html">Linear documentation</a> grouped only by classes, declared
index 75fbe089438725870291f755776561e9d291be8d..03ae8e0f8f5f3756429b38cb089e73718fe82641 100644 (file)
@@ -149,7 +149,7 @@ module SMESH
     SALOMEDS::Study GetCurrentStudy();
 
     /*!
-     * Create a hypothesis that can be shared by differents parts of the mesh.
+     * Create a hypothesis that can be shared by different parts of the mesh.
      * An hypothesis is either:
      * - a method used to generate or modify a part of the mesh (algorithm).
      * - a parameter or a law used by an algorithm.
index 805b21df68590e0e04a7c16b1de072b6bd6eba82..74619a175b81847b1015b226d0ee61131f29adac 100644 (file)
@@ -191,6 +191,7 @@ module SMESH
     Entity_TriQuad_Hexa,
     Entity_Penta,
     Entity_Quad_Penta,
+    Entity_BiQuad_Penta,
     Entity_Hexagonal_Prism,
     Entity_Polyhedra,
     Entity_Quad_Polyhedra,
@@ -237,11 +238,28 @@ module SMESH
 
   /*!
    * Enumeration for ExportToMED*()
+   * MED_V2_1 and MED_V2_2 are here for compatibility and mean respectively obsolete and MED_LATEST.
+   * MED_MINOR_0 to MED_MINOR_9 are use to specify the minor version used by MEDfichier
+   * to write MED files (major version cannot be changed).
+   * This allows backward compatibility from a newer version of SALOME to an older one:
+   * for instance, a MESH produced in SALOME 8.4 (med 3.3) can be written in med 3.2 format
+   * to be read in SALOME 8.3.
    */
   enum MED_VERSION
   {
     MED_V2_1,
-    MED_V2_2
+    MED_V2_2,
+    MED_LATEST,
+    MED_MINOR_0,
+    MED_MINOR_1,
+    MED_MINOR_2,
+    MED_MINOR_3,
+    MED_MINOR_4,
+    MED_MINOR_5,
+    MED_MINOR_6,
+    MED_MINOR_7,
+    MED_MINOR_8,
+    MED_MINOR_9
   };
 
   /*! 
@@ -685,8 +703,8 @@ module SMESH
       raises (SALOME::SALOME_Exception);
 
     /*!
-     * Export Mesh to MED_V2_1 MED format
-     * Works, just the same as ExportToMEDX with MED_VERSION parameter equal to MED_V2_1
+     * Export Mesh to MED_LATEST MED format
+     * Works, just the same as ExportToMEDX with MED_VERSION parameter equal to MED_LATEST
      * and overwrite parameter equal to true
      * The method is kept in order to support old functionality
      */
@@ -715,7 +733,8 @@ module SMESH
                     in boolean isascii ) raises (SALOME::SALOME_Exception);
     void ExportCGNS( in SMESH_IDSource meshPart, 
                      in string         file,
-                     in boolean        overwrite ) raises (SALOME::SALOME_Exception);
+                     in boolean        overwrite,
+                     in boolean        groupElemsByType) raises (SALOME::SALOME_Exception);
     void ExportGMF( in SMESH_IDSource  meshPart, 
                     in string          file,
                     in boolean         withRequiredGroups) raises (SALOME::SALOME_Exception);
@@ -975,6 +994,11 @@ module SMESH
      */
     long FindElementByNodes(in long_array nodes);
 
+    /*!
+     * Return elements including all given nodes.
+     */
+    long_array GetElementsByNodes(in long_array nodes, in ElementType elem_type);
+
     /*!
      * Returns true if given element is polygon
      */
index 6e80cc77ad1a53324ea380b885c3cc6eb78c1a8b..9333e702377047a93173cfb392bf6288967740da 100644 (file)
@@ -616,7 +616,8 @@ double MaxElementLength3D::GetValue( long theElementId )
       aVal = Max(aVal,Max(L7,L8));
       break;
     }
-    case SMDSEntity_Quad_Penta: { // quadratic pentas
+    case SMDSEntity_Quad_Penta:
+    case SMDSEntity_BiQuad_Penta: { // quadratic pentas
       double L1 = getDistance(P( 1 ),P( 7 )) + getDistance(P( 7 ),P( 2 ));
       double L2 = getDistance(P( 2 ),P( 8 )) + getDistance(P( 8 ),P( 3 ));
       double L3 = getDistance(P( 3 ),P( 9 )) + getDistance(P( 9 ),P( 1 ));
@@ -1619,7 +1620,7 @@ double Length2D::GetValue( long theElementId )
       }
       break;
     case SMDSEntity_Pyramid:
-      if (len == 5){ // piramids
+      if (len == 5){ // pyramid
         double L1 = getDistance(P( 1 ),P( 2 ));
         double L2 = getDistance(P( 2 ),P( 3 ));
         double L3 = getDistance(P( 3 ),P( 4 ));
@@ -1634,7 +1635,7 @@ double Length2D::GetValue( long theElementId )
       }
       break;
     case SMDSEntity_Penta:
-      if (len == 6) { // pentaidres
+      if (len == 6) { // pentahedron
         double L1 = getDistance(P( 1 ),P( 2 ));
         double L2 = getDistance(P( 2 ),P( 3 ));
         double L3 = getDistance(P( 3 ),P( 1 ));
@@ -1670,7 +1671,7 @@ double Length2D::GetValue( long theElementId )
       }
       break;
     case SMDSEntity_Quad_Tetra:
-      if (len == 10){ // quadratic tetraidrs
+      if (len == 10){ // quadratic tetrahedron
         double L1 = getDistance(P( 1 ),P( 5 )) + getDistance(P( 5 ),P( 2 ));
         double L2 = getDistance(P( 2 ),P( 6 )) + getDistance(P( 6 ),P( 3 ));
         double L3 = getDistance(P( 3 ),P( 7 )) + getDistance(P( 7 ),P( 1 ));
@@ -1681,7 +1682,7 @@ double Length2D::GetValue( long theElementId )
       }
       break;
     case SMDSEntity_Quad_Pyramid:
-      if (len == 13){ // quadratic piramids
+      if (len == 13){ // quadratic pyramid
         double L1 = getDistance(P( 1 ),P( 6 )) + getDistance(P( 6 ),P( 2 ));
         double L2 = getDistance(P( 2 ),P( 7 )) + getDistance(P( 7 ),P( 3 ));
         double L3 = getDistance(P( 3 ),P( 8 )) + getDistance(P( 8 ),P( 4 ));
@@ -1695,7 +1696,8 @@ double Length2D::GetValue( long theElementId )
       }
       break;
     case SMDSEntity_Quad_Penta:
-      if (len == 15){ // quadratic pentaidres
+    case SMDSEntity_BiQuad_Penta:
+      if (len >= 15){ // quadratic pentahedron
         double L1 = getDistance(P( 1 ),P( 7 )) + getDistance(P( 7 ),P( 2 ));
         double L2 = getDistance(P( 2 ),P( 8 )) + getDistance(P( 8 ),P( 3 ));
         double L3 = getDistance(P( 3 ),P( 9 )) + getDistance(P( 9 ),P( 1 ));
@@ -1711,7 +1713,7 @@ double Length2D::GetValue( long theElementId )
       break;
     case SMDSEntity_Quad_Hexa:
     case SMDSEntity_TriQuad_Hexa:
-      if (len >= 20) { // quadratic hexaider
+      if (len >= 20) { // quadratic hexahedron
         double L1 = getDistance(P( 1 ),P( 9 )) + getDistance(P( 9 ),P( 2 ));
         double L2 = getDistance(P( 2 ),P( 10 )) + getDistance(P( 10 ),P( 3 ));
         double L3 = getDistance(P( 3 ),P( 11 )) + getDistance(P( 11 ),P( 4 ));
@@ -4287,6 +4289,7 @@ void ElementsOnShape::SetShape (const TopoDS_Shape&       theShape,
 
   if ( shapeChanges )
   {
+    // find most complex shapes
     TopTools_IndexedMapOfShape shapesMap;
     TopAbs_ShapeEnum shapeTypes[4] = { TopAbs_SOLID, TopAbs_FACE, TopAbs_EDGE, TopAbs_VERTEX };
     TopExp_Explorer sub;
@@ -4329,10 +4332,18 @@ void ElementsOnShape::clearClassifiers()
 
 bool ElementsOnShape::IsSatisfy( long elemId )
 {
-  const SMDS_Mesh*        mesh = myMeshModifTracer.GetMesh();
-  const SMDS_MeshElement* elem =
-    ( myType == SMDSAbs_Node ? mesh->FindNode( elemId ) : mesh->FindElement( elemId ));
-  if ( !elem || myClassifiers.empty() )
+  if ( myClassifiers.empty() )
+    return false;
+
+  const SMDS_Mesh* mesh = myMeshModifTracer.GetMesh();
+  if ( myType == SMDSAbs_Node )
+    return IsSatisfy( mesh->FindNode( elemId ));
+  return IsSatisfy( mesh->FindElement( elemId ));
+}
+
+bool ElementsOnShape::IsSatisfy (const SMDS_MeshElement* elem)
+{
+  if ( !elem )
     return false;
 
   bool isSatisfy = myAllNodesFlag, isNodeOut;
@@ -4396,6 +4407,60 @@ bool ElementsOnShape::IsSatisfy( long elemId )
   return isSatisfy;
 }
 
+bool ElementsOnShape::IsSatisfy (const SMDS_MeshNode* node,
+                                 TopoDS_Shape*        okShape)
+{
+  if ( !node )
+    return false;
+
+  if ( !myOctree && myClassifiers.size() > 5 )
+  {
+    myWorkClassifiers.resize( myClassifiers.size() );
+    for ( size_t i = 0; i < myClassifiers.size(); ++i )
+      myWorkClassifiers[ i ] = & myClassifiers[ i ];
+    myOctree = new OctreeClassifier( myWorkClassifiers );
+  }
+
+  bool isNodeOut = true;
+
+  if ( okShape || !getNodeIsOut( node, isNodeOut ))
+  {
+    SMESH_NodeXYZ aPnt = node;
+    if ( myOctree )
+    {
+      myWorkClassifiers.clear();
+      myOctree->GetClassifiersAtPoint( aPnt, myWorkClassifiers );
+
+      for ( size_t i = 0; i < myWorkClassifiers.size(); ++i )
+        myWorkClassifiers[i]->SetChecked( false );
+
+      for ( size_t i = 0; i < myWorkClassifiers.size(); ++i )
+        if ( !myWorkClassifiers[i]->IsChecked() &&
+             !myWorkClassifiers[i]->IsOut( aPnt ))
+        {
+          isNodeOut = false;
+          if ( okShape )
+            *okShape = myWorkClassifiers[i]->Shape();
+          break;
+        }
+    }
+    else
+    {
+      for ( size_t i = 0; i < myClassifiers.size(); ++i )
+        if ( !myClassifiers[i].IsOut( aPnt ))
+        {
+          isNodeOut = false;
+          if ( okShape )
+            *okShape = myWorkClassifiers[i]->Shape();
+          break;
+        }
+    }
+    setNodeIsOut( node, isNodeOut );
+  }
+
+  return !isNodeOut;
+}
+
 void ElementsOnShape::Classifier::Init( const TopoDS_Shape& theShape,
                                         double              theTol,
                                         const Bnd_B3d*      theBox )
@@ -4493,7 +4558,7 @@ bool ElementsOnShape::Classifier::isOutOfFace  (const gp_Pnt& p)
   if ( myProjFace.IsDone() && myProjFace.LowerDistance() <= myTol )
   {
     // check relatively to the face
-    Quantity_Parameter u, v;
+    Standard_Real u, v;
     myProjFace.LowerDistanceParameters(u, v);
     gp_Pnt2d aProjPnt (u, v);
     BRepClass_FaceClassifier aClsf ( TopoDS::Face( myShape ), aProjPnt, myTol );
index cd39ab3d95d820f98bc0a86e633d3821d8a50607..74a4a263d270b1d0efb9f25506e7ccab49fe0bbe 100644 (file)
@@ -902,6 +902,8 @@ namespace SMESH{
       bool    GetAllNodes() const { return myAllNodesFlag; }
       void    SetShape (const TopoDS_Shape& theShape,
                         const SMDSAbs_ElementType theType);
+      bool    IsSatisfy (const SMDS_MeshElement* elem);
+      bool    IsSatisfy (const SMDS_MeshNode* node, TopoDS_Shape* okShape=0);
 
     private:
 
index 844bb863fb224023fed8656ba464d80ec2b2e729..4d79e0f7cca78c3a0b275f5c1ce2735b09e3eb5a 100644 (file)
@@ -25,6 +25,7 @@
 
 #include "DriverCGNS_Write.hxx"
 
+#include "SMDS_IteratorOnIterators.hxx"
 #include "SMDS_MeshNode.hxx"
 #include "SMDS_VolumeTool.hxx"
 #include "SMESHDS_GroupBase.hxx"
@@ -129,6 +130,11 @@ namespace
         interlaces[SMDSEntity_Quad_Penta] = ids;
         cgTypes   [SMDSEntity_Quad_Penta] = CGNS_ENUMV( PENTA_15 );
       }
+      {
+        static int ids[] = { 0,2,1,3,5,4,8,7,6,9,11,10,14,13,12,15,16,17 }; // TODO: check CGNS ORDER
+        interlaces[SMDSEntity_BiQuad_Penta] = ids;
+        cgTypes   [SMDSEntity_BiQuad_Penta] = CGNS_ENUMV( PENTA_18 );
+      }
       {
         static int ids[] = { 0,3,2,1,4,7,6,5 };
         interlaces[SMDSEntity_Hexa] = ids;
@@ -330,7 +336,24 @@ Driver_Mesh::Status DriverCGNS_Write::Perform()
   // write into a section all successive elements of one geom type
   int iSec;
   vector< cgsize_t > elemData;
-  SMDS_ElemIteratorPtr  elemIt = myMesh->elementsIterator();
+  SMDS_ElemIteratorPtr elemIt = myMesh->elementsIterator();
+  vector< SMDS_ElemIteratorPtr > elemItVec;
+  if ( _elementsByType )
+  {
+    // create an iterator returning all elements by type
+    for ( int type = SMDSEntity_Node + 1; type < SMDSEntity_Last; ++type )
+    {
+      if ( type == SMDSEntity_Ball )
+        continue; // not supported
+      elemIt = myMesh->elementEntityIterator( SMDSAbs_EntityType( type ));
+      if ( elemIt->more() )
+        elemItVec.push_back( elemIt );
+    }
+    typedef SMDS_IteratorOnIterators< const SMDS_MeshElement*,
+                                      vector< SMDS_ElemIteratorPtr > > TVecIterator;
+    elemIt.reset( new TVecIterator( elemItVec ));
+  }
+
   const SMDS_MeshElement* elem = elemIt->next();
   while ( elem )
   {
@@ -397,6 +420,15 @@ Driver_Mesh::Status DriverCGNS_Write::Perform()
         elem = elemIt->more() ? elemIt->next() : 0;
       continue;
     }
+    else // skip NOT SUPPORTED elements
+    {
+      while ( elemIt->more() )
+      {
+        elem = elemIt->next();
+        if ( elem->GetEntityType() != elemType )
+          break;
+      }
+    }
 
     SMESH_Comment sectionName( cg_ElementTypeName( cgType ));
     sectionName << " " << startID << " - " << cgID-1;
@@ -405,6 +437,7 @@ Driver_Mesh::Status DriverCGNS_Write::Perform()
                           cgID-1, /*nbndry=*/0, &elemData[0], &iSec) != CG_OK )
       return addMessage( cg_get_error(), /*fatal = */true );
   }
+
   // Write polyhedral volumes
   // -------------------------
 
@@ -534,21 +567,33 @@ Driver_Mesh::Status DriverCGNS_Write::Perform()
       switch ( meshDim ) {
       case 3:
         switch ( group->GetType() ) {
-        case SMDSAbs_Volume: location = CGNS_ENUMV( FaceCenter ); break; // !!!
-        case SMDSAbs_Face:   location = CGNS_ENUMV( FaceCenter ); break; // OK
-        case SMDSAbs_Edge:   location = CGNS_ENUMV( EdgeCenter ); break; // OK
+#if CGNS_VERSION > 3130
+        case SMDSAbs_Volume: location = CGNS_ENUMV( CellCenter ); break;
+#else
+        case SMDSAbs_Volume: location = CGNS_ENUMV( FaceCenter ); break;
+#endif
+        case SMDSAbs_Face:   location = CGNS_ENUMV( FaceCenter ); break;
+        case SMDSAbs_Edge:   location = CGNS_ENUMV( EdgeCenter ); break;
         default:;
         }
         break;
       case 2:
         switch ( group->GetType() ) {
-        case SMDSAbs_Face: location = CGNS_ENUMV( FaceCenter ); break; // ???
-        case SMDSAbs_Edge: location = CGNS_ENUMV( EdgeCenter ); break; // OK
+#if CGNS_VERSION > 3130
+        case SMDSAbs_Face: location = CGNS_ENUMV( CellCenter ); break;
+#else
+        case SMDSAbs_Face: location = CGNS_ENUMV( FaceCenter ); break;
+#endif
+        case SMDSAbs_Edge: location = CGNS_ENUMV( EdgeCenter ); break;
         default:;
         }
         break;
       case 1:
-        location = CGNS_ENUMV( EdgeCenter ); break; // ???
+#if CGNS_VERSION > 3130
+        location = CGNS_ENUMV( CellCenter ); break;
+#else
+        location = CGNS_ENUMV( EdgeCenter ); break;
+#endif
         break;
       }
     }
@@ -556,9 +601,16 @@ Driver_Mesh::Status DriverCGNS_Write::Perform()
     // try to extract type of boundary condition from the group name
     string name = group->GetStoreName();
     CGNS_ENUMT( BCType_t ) bcType = getBCType( name );
-    while ( !groupNames.insert( name ).second )
-      name = (SMESH_Comment( "Group_") << groupNames.size());
-
+    if ( !groupNames.insert( name ).second ) // assure name uniqueness
+    {
+      int index = 1;
+      string newName;
+      do {
+        newName = SMESH_Comment( name ) << "_" << index++;
+      }
+      while ( !groupNames.insert( newName ).second );
+      name = newName;
+    }
     // write IDs of elements
     vector< cgsize_t > pnts;
     pnts.reserve( group->Extent() );
@@ -568,13 +620,15 @@ Driver_Mesh::Status DriverCGNS_Write::Perform()
       const SMDS_MeshElement* elem = elemIt->next();
       pnts.push_back( cgnsID( elem, elem2cgIDByEntity[ elem->GetEntityType() ]));
     }
+    if ( pnts.size() == 0 )
+      continue; // can't store empty group
     int iBC;
     if ( cg_boco_write( _fn, iBase, iZone, name.c_str(), bcType,
                         CGNS_ENUMV( PointList ), pnts.size(), &pnts[0], &iBC) != CG_OK )
       return addMessage( cg_get_error(), /*fatal = */true);
 
     // write BC location
-    if ( location != CGNS_ENUMV( Vertex ))
+    if ( location != CGNS_ENUMV( Vertex ) || meshDim == 1 )
     {
       if ( cg_boco_gridlocation_write( _fn, iBase, iZone, iBC, location) != CG_OK )
         return addMessage( cg_get_error(), /*fatal = */false);
@@ -589,7 +643,7 @@ Driver_Mesh::Status DriverCGNS_Write::Perform()
  */
 //================================================================================
 
-DriverCGNS_Write::DriverCGNS_Write(): _fn(0)
+DriverCGNS_Write::DriverCGNS_Write(): _fn(0), _elementsByType( false )
 {
 }
 
index e427f97541296039480173161e29fbe7d209b948..fd0ba22398ce0f8a2a758989a575e8cabc50efd3 100644 (file)
@@ -45,9 +45,16 @@ public:
 
   virtual Status Perform();
 
+  // to export elements either in the order of their IDs or by geometric type
+  void SetElementsByType( bool isByType ) { _elementsByType = isByType; }
+
 private:
 
   int _fn; //!< file index
+
+  // if true all elements of same geometry are exported at ones,
+  // else elements are exported in order of their IDs
+  bool _elementsByType;
 };
 
 #endif
index 16c555eaf4723c41a7dfb138aea43e0d6f266f54..b3c91db53016b0149fc8870e29f6c4201a26d41e 100644 (file)
@@ -493,6 +493,7 @@ Driver_Mesh::Status DriverMED_R_SMESHDS_Mesh::Perform()
             case ePYRA13:  aNbNodes = 13; break;
             case ePENTA6:  aNbNodes = 6;  break;
             case ePENTA15: aNbNodes = 15; break;
+            case ePENTA18: aNbNodes = 18; break;
             case eHEXA8:   aNbNodes = 8;  break;
             case eHEXA20:  aNbNodes = 20; break;
             case eHEXA27:  aNbNodes = 27; break;
@@ -811,6 +812,41 @@ Driver_Mesh::Status DriverMED_R_SMESHDS_Mesh::Perform()
                     isRenum = anIsElemNum;
                   }
                   break;
+                case ePENTA18:
+                  aNbNodes = 18;
+                  if(anIsElemNum)
+                    anElement = myMesh->AddVolumeWithID(aNodeIds[0], aNodeIds[1],
+                                                        aNodeIds[2], aNodeIds[3],
+                                                        aNodeIds[4], aNodeIds[5],
+                                                        aNodeIds[6], aNodeIds[7],
+                                                        aNodeIds[8], aNodeIds[9],
+                                                        aNodeIds[10], aNodeIds[11],
+                                                        aNodeIds[12], aNodeIds[13],
+                                                        aNodeIds[14], aNodeIds[15],
+                                                        aNodeIds[16], aNodeIds[17],
+                                                        aCellInfo->GetElemNum(iElem));
+                  if (!anElement) {
+                    anElement = myMesh->AddVolume(FindNode(myMesh,aNodeIds[0]),
+                                                  FindNode(myMesh,aNodeIds[1]),
+                                                  FindNode(myMesh,aNodeIds[2]),
+                                                  FindNode(myMesh,aNodeIds[3]),
+                                                  FindNode(myMesh,aNodeIds[4]),
+                                                  FindNode(myMesh,aNodeIds[5]),
+                                                  FindNode(myMesh,aNodeIds[6]),
+                                                  FindNode(myMesh,aNodeIds[7]),
+                                                  FindNode(myMesh,aNodeIds[8]),
+                                                  FindNode(myMesh,aNodeIds[9]),
+                                                  FindNode(myMesh,aNodeIds[10]),
+                                                  FindNode(myMesh,aNodeIds[11]),
+                                                  FindNode(myMesh,aNodeIds[12]),
+                                                  FindNode(myMesh,aNodeIds[13]),
+                                                  FindNode(myMesh,aNodeIds[14]),
+                                                  FindNode(myMesh,aNodeIds[15]),
+                                                  FindNode(myMesh,aNodeIds[16]),
+                                                  FindNode(myMesh,aNodeIds[17]));
+                    isRenum = anIsElemNum;
+                  }
+                  break;
                 case eHEXA8:
                   aNbNodes = 8;
                   if(anIsElemNum)
index e4a7e422012909aa183bd34e26ea4d3b152984c0..b012325bcbe92b46f501ceed7211296e9f8b7985 100644 (file)
@@ -393,6 +393,7 @@ namespace DriverMED // Implemetation of fuctions declared in DriverMED.hxx
       theVec[ SMDSEntity_TriQuad_Hexa       ] = MED::eHEXA27  ;
       theVec[ SMDSEntity_Penta              ] = MED::ePENTA6  ;
       theVec[ SMDSEntity_Quad_Penta         ] = MED::ePENTA15 ;
+      theVec[ SMDSEntity_BiQuad_Penta       ] = MED::ePENTA18 ;
       theVec[ SMDSEntity_Hexagonal_Prism    ] = MED::eOCTA12  ;
       theVec[ SMDSEntity_Polyhedra          ] = MED::ePOLYEDRE;
       //theVec[ SMDSEntity_Quad_Polyhedra     ] = MED::ePOLYEDRE; // !!
index 64d6b6a3b687b3ac68c3030c1cb28744e93107b0..82722c15f3e4f327e412a593d228d6eaaa165c63 100644 (file)
@@ -70,6 +70,7 @@ void DriverMED_W_SMESHDS_Mesh::SetFile(const std::string& theFileName,
 {
   Driver_SMESHDS_Mesh::SetFile(theFileName);
   myMedVersion = theId;
+  //MESSAGE("myMedVersion:"<<myMedVersion);
 }
 
 void DriverMED_W_SMESHDS_Mesh::SetFile(const std::string& theFileName)
@@ -77,19 +78,39 @@ void DriverMED_W_SMESHDS_Mesh::SetFile(const std::string& theFileName)
   Driver_SMESHDS_Mesh::SetFile(theFileName);
 }
 
+/*!
+ * MED version is either the latest available, or with an inferior minor,
+ * to ensure backward compatibility on writing med files.
+ */
 string DriverMED_W_SMESHDS_Mesh::GetVersionString(const MED::EVersion theVersion, int theNbDigits)
 {
   TInt majeur, mineur, release;
   majeur =  mineur = release = 0;
-//   if ( theVersion == eV2_1 )
-//     MED::GetVersionRelease<eV2_1>(majeur, mineur, release);
-//   else
-    MED::GetVersionRelease<eV2_2>(majeur, mineur, release);
+  MED::GetVersionRelease<eV2_2>(majeur, mineur, release);
+  TInt imposedMineur = mineur;
+  switch( theVersion ) {
+    case MED::eV2_1     :
+    case MED::eV2_2     :
+    case MED::eLATEST   : break;
+    case MED::eMINOR_0  : imposedMineur = 0; break;
+    case MED::eMINOR_1  : imposedMineur = 1; break;
+    case MED::eMINOR_2  : imposedMineur = 2; break;
+    case MED::eMINOR_3  : imposedMineur = 3; break;
+    case MED::eMINOR_4  : imposedMineur = 4; break;
+    case MED::eMINOR_5  : imposedMineur = 5; break;
+    case MED::eMINOR_6  : imposedMineur = 6; break;
+    case MED::eMINOR_7  : imposedMineur = 7; break;
+    case MED::eMINOR_8  : imposedMineur = 8; break;
+    case MED::eMINOR_9  : imposedMineur = 9; break;
+    case MED::eVUnknown : imposedMineur = mineur; break;
+  }
+  if (imposedMineur > mineur)
+    imposedMineur = mineur;
   ostringstream name;
   if ( theNbDigits > 0 )
     name << majeur;
   if ( theNbDigits > 1 )
-    name << "." << mineur;
+    name << "." << imposedMineur;
   if ( theNbDigits > 2 )
     name << "." << release;
   return name.str();
@@ -456,7 +477,7 @@ Driver_Mesh::Status DriverMED_W_SMESHDS_Mesh::Perform()
         break;
       }
     }
-
+    //MESSAGE("myMedVersion:"<<myMedVersion);
     MED::PWrapper myMed = CrWrapper(myFile,myMedVersion);
     PMeshInfo aMeshInfo = myMed->CrMeshInfo(aMeshDimension,aSpaceDimension,aMeshName);
     //MESSAGE("Add - aMeshName : "<<aMeshName<<"; "<<aMeshInfo->GetName());
@@ -703,7 +724,11 @@ Driver_Mesh::Status DriverMED_W_SMESHDS_Mesh::Perform()
                                              SMDSAbs_Volume));
     aTElemTypeDatas.push_back( TElemTypeData(anEntity,
                                              ePENTA15,
-                                             nbElemInfo.NbPrisms( ORDER_QUADRATIC ),
+                                             nbElemInfo.NbQuadPrisms(),
+                                             SMDSAbs_Volume));
+    aTElemTypeDatas.push_back( TElemTypeData(anEntity,
+                                             ePENTA18,
+                                             nbElemInfo.NbBiQuadPrisms(),
                                              SMDSAbs_Volume));
     aTElemTypeDatas.push_back( TElemTypeData(anEntity,
                                              eHEXA8,
@@ -943,7 +968,6 @@ Driver_Mesh::Status DriverMED_W_SMESHDS_Mesh::Perform()
       {
         // Treat standard types
         // ---------------------
-
         // allocate data arrays
         PCellInfo aCellInfo = myMed->CrCellInfo( aMeshInfo,
                                                  aElemTypeData->_entity,
@@ -955,7 +979,6 @@ Driver_Mesh::Status DriverMED_W_SMESHDS_Mesh::Perform()
         // build map of family numbers for this type
         if ( !isElemFamMapBuilt[ aElemTypeData->_smdsType ])
         {
-          //cout << " fillElemFamilyMap()" << endl;
           fillElemFamilyMap( anElemFamMap, aFamilies, aElemTypeData->_smdsType );
           isElemFamMapBuilt[ aElemTypeData->_smdsType ] = true;
         }
@@ -993,10 +1016,7 @@ Driver_Mesh::Status DriverMED_W_SMESHDS_Mesh::Perform()
         // store data in a file
         myMed->SetCellInfo(aCellInfo);
       }
-
     } // loop on geom types
-
-
   }
   catch(const std::exception& exc) {
     INFOS("The following exception was caught:\n\t"<<exc.what());
index 390e1d623d49f0b8883b85b1937bd96fdcbe1e2d..00eb32bdf3410f694946450c13c5ed022973668a 100644 (file)
 #endif
 
 namespace MED{
-
-  enum EVersion {eVUnknown = -1, eV2_1, eV2_2};
+  // enum EVersion sould be synchronized with enum MED_VERSION in SMESH_Mesh.idl (.hh)
+  // i.e. same positive values!
+  enum EVersion {eVUnknown = -1, eV2_1, eV2_2, eLATEST,
+                 eMINOR_0, eMINOR_1, eMINOR_2, eMINOR_3, eMINOR_4, eMINOR_5, eMINOR_6, eMINOR_7, eMINOR_8, eMINOR_9};
   
   typedef enum {eFAUX, eVRAI} EBooleen ; 
   typedef double TFloat;
@@ -70,7 +72,7 @@ namespace MED{
   typedef enum {ePOINT1=1, eSEG2=102, eSEG3=103, eTRIA3=203,
                 eQUAD4=204, eTRIA6=206, eTRIA7=207, eQUAD8=208, eQUAD9=209,eTETRA4=304,
                 ePYRA5=305, ePENTA6=306, eHEXA8=308, eOCTA12=312, eTETRA10=310, 
-                ePYRA13=313, ePENTA15=315, eHEXA20=320, eHEXA27=327,
+                ePYRA13=313, ePENTA15=315, ePENTA18=318, eHEXA20=320, eHEXA27=327,
                 ePOLYGONE=400, ePOLYGON2=420, ePOLYEDRE=500, eNONE=0, 
                 eBALL=1101 /*no such a type in med.h, it's just a trick*/,
                 eAllGeoType=-1 } EGeometrieElement;
index b2475c8c096500b9e4000d87711b6278bcfd3896..8d33db5fd0648d27a29af5340b94dacd9bc83f74 100644 (file)
@@ -27,7 +27,7 @@
 #ifdef WIN32
 #pragma warning(disable:4250)
 #endif
-
+#include <utilities.h>
 namespace MED
 {
   //---------------------------------------------------------------
index 7366f22d8a9343fd21511304a6c6aec4bf7d1554..1ba7bbdbc74fb44fa82b05140babd8aef3d570c6 100644 (file)
@@ -93,6 +93,7 @@ bool InitEntity2GeomSet()
   aGeomMAILLESet.insert(eTETRA10);
   aGeomMAILLESet.insert(ePYRA13);
   aGeomMAILLESet.insert(ePENTA15);
+  aGeomMAILLESet.insert(ePENTA18);
   aGeomMAILLESet.insert(eHEXA20);
   aGeomMAILLESet.insert(eHEXA27);
   aGeomMAILLESet.insert(ePOLYEDRE);
index 49d47fad57d72413dfafdc7e48e6bc47e0a0a135..6c1d9909b8b0e4f77c1c228e07bcfc398dfde8c2 100644 (file)
@@ -23,7 +23,6 @@
 #include "MED_Factory.hxx"
 #include "MED_Utilities.hxx"
 #include "MED_V2_2_Wrapper.hxx"
-
 #include <stdio.h>
 #include <errno.h>
 #include <sstream>
@@ -90,6 +89,7 @@ namespace MED
         if(aMajor == 2 && aMinor == 1)
           aVersion = eV2_1;
         else
+          // TODO: check major is not superior to library and switch on minor
           aVersion = eV2_2;
       }
       else {
@@ -124,20 +124,19 @@ namespace MED
   }
 
   PWrapper CrWrapper(const std::string& theFileName,
-                     bool theDoPreCheckInSeparateProcess)
+                     bool theDoPreCheckInSeparateProcess,
+                     int  theMinor)
   {
     PWrapper aWrapper;
+    if (theMinor <0)
+      theMinor = MED_MINOR_NUM;
     EVersion aVersion = GetVersionId(theFileName,theDoPreCheckInSeparateProcess);
     switch(aVersion){
-    case eV2_2:
-      aWrapper.reset(new MED::V2_2::TVWrapper(theFileName));
-      break;
     case eV2_1:
       EXCEPTION(std::runtime_error,"Cannot open file '"<<theFileName<<"'. Med version 2.1 is not supported any more.");
-      //aWrapper.reset(new MED::V2_1::TVWrapper(theFileName));
       break;
     default:
-      EXCEPTION(std::runtime_error,"MED::CrWrapper - theFileName = '"<<theFileName<<"'");
+      aWrapper.reset(new MED::V2_2::TVWrapper(theFileName, theMinor));
     }
     return aWrapper;
   }
@@ -145,22 +144,29 @@ namespace MED
   PWrapper CrWrapper(const std::string& theFileName, EVersion theId)
   {
     EVersion aVersion = GetVersionId(theFileName);
+    if (aVersion == eVUnknown) // no existing file
+      aVersion = theId;
 
     if(aVersion != theId)
-      remove(theFileName.c_str());
-    
-    PWrapper aWrapper;
-    switch(theId){
-    case eV2_2:
-      aWrapper.reset(new MED::V2_2::TVWrapper(theFileName));
-      break;
-    case eV2_1:
-      EXCEPTION(std::runtime_error,"Cannot open file '"<<theFileName<<"'. Med version 2.1 is not supported any more.");
-      //aWrapper.reset(new MED::V2_1::TVWrapper(theFileName));
-      break;
-    default:
-      aWrapper.reset(new MED::V2_2::TVWrapper(theFileName));
+      //remove(theFileName.c_str());
+      EXCEPTION(std::runtime_error,"Cannot open file for writing '"<<theFileName<<"'. existing file with another Med version.");
+
+    aVersion = theId;
+    int theMinor = -1; // not supported
+    switch (aVersion)
+    {
+      case eV2_1:     break; // not supported
+      case eVUnknown:
+      case eV2_2:
+      case eLATEST:   theMinor = MED_MINOR_NUM; break;
+      default:        theMinor = aVersion - eMINOR_0;
     }
+
+    if (theMinor < 0)
+      EXCEPTION(std::runtime_error,"Cannot open file '"<<theFileName<<"'. Med version 2.1 is not supported any more.");
+
+    PWrapper aWrapper;
+    aWrapper.reset(new MED::V2_2::TVWrapper(theFileName, theMinor));
     return aWrapper;
   }
 
index f64ba391bd4c20d2d9b3f84ae9bbe4910ab176ed..fc710864ebe538e1927ff6c1e9ef93bd4f3f30c7 100644 (file)
@@ -39,7 +39,8 @@ namespace MED
   MEDWRAPPER_FACTORY_EXPORT
   PWrapper 
   CrWrapper(const std::string& theFileName,
-            bool theDoPreCheckInSeparateProcess = false);
+            bool theDoPreCheckInSeparateProcess = false,
+            int theMinor=-1);
 
   MEDWRAPPER_FACTORY_EXPORT
   PWrapper 
index 934839742e4bb013a7fb8fb5854f2fa98d9a792a..344542ebc9a0c11e63bc0d42819e173659b62839 100644 (file)
@@ -26,6 +26,7 @@
 
 #include <med.h>
 #include <med_err.h>
+#include <med_proto.h>
 
 #ifdef _DEBUG_
 static int MYDEBUG = 0;
@@ -99,11 +100,14 @@ namespace MED
       TFile(const TFile&);
       
     public:
-      TFile(const std::string& theFileName): 
+      TFile(const std::string& theFileName, TInt theMinor=-1):
         myCount(0),
         myFid(0), 
-        myFileName(theFileName)
-      {}
+        myFileName(theFileName),
+        myMinor(theMinor)
+      {
+        if ((myMinor < 0) || (myMinor > MED_MINOR_NUM)) myMinor = MED_MINOR_NUM;
+      }
       
       ~TFile()
       { 
@@ -115,12 +119,12 @@ namespace MED
       {
         if(myCount++ == 0){
           const char* aFileName = myFileName.c_str();
-          myFid = MEDfileOpen(aFileName,med_access_mode(theMode));
+          myFid = MEDfileVersionOpen(aFileName,med_access_mode(theMode), MED_MAJOR_NUM, myMinor, MED_RELEASE_NUM);
         }
         if(theErr)
           *theErr = TErr(myFid);
         else if(myFid < 0)
-          EXCEPTION(std::runtime_error,"TFile - MEDfileOpen('"<<myFileName<<"',"<<theMode<<")");
+          EXCEPTION(std::runtime_error,"TFile - MEDfileVersionOpen('"<<myFileName<<"',"<<theMode<<"',"<< MED_MAJOR_NUM<<"',"<< myMinor<<"',"<< MED_RELEASE_NUM<<")");
       }
 
       const TIdt& Id() const 
@@ -140,6 +144,7 @@ namespace MED
       TInt myCount;
       TIdt myFid;
       std::string myFileName;
+      TInt myMinor;
     };
 
 
@@ -147,11 +152,14 @@ namespace MED
     class TFileWrapper
     {
       PFile myFile;
+      TInt myMinor;
 
     public:
-      TFileWrapper(const PFile& theFile, EModeAcces theMode, TErr* theErr = NULL): 
-        myFile(theFile)
+      TFileWrapper(const PFile& theFile, EModeAcces theMode, TErr* theErr = NULL, TInt theMinor=-1):
+        myFile(theFile),
+        myMinor(theMinor)
       {
+        if (myMinor < 0) myMinor = MED_MINOR_NUM;
         myFile->Open(theMode,theErr);
       }
       
@@ -163,15 +171,12 @@ namespace MED
 
 
     //---------------------------------------------------------------
-    TVWrapper::TVWrapper(const std::string& theFileName):
-      myFile(new TFile(theFileName))
+    TVWrapper::TVWrapper(const std::string& theFileName, TInt theMinor):
+      myMinor(theMinor),
+      myFile(new TFile(theFileName, theMinor))
     {
       TErr aRet;
       myFile->Open( eLECTURE_ECRITURE, &aRet );
-      // if(aRet < 0)
-      //   myFile->Close();
-      //   myFile->Open( eLECTURE_AJOUT, &aRet );
-      // }
       if(aRet < 0) {
         myFile->Close();
         myFile->Open( eLECTURE, &aRet );
@@ -188,7 +193,7 @@ namespace MED
     TVWrapper
     ::GetNbMeshes(TErr* theErr)
     {
-      TFileWrapper aFileWrapper(myFile,eLECTURE,theErr);
+      TFileWrapper aFileWrapper(myFile,eLECTURE,theErr, myMinor);
       
       if(theErr && *theErr < 0)
         return -1;
@@ -204,7 +209,7 @@ namespace MED
                   MED::TMeshInfo& theInfo,
                   TErr* theErr)
     {
-      TFileWrapper aFileWrapper(myFile,eLECTURE,theErr);
+      TFileWrapper aFileWrapper(myFile,eLECTURE,theErr, myMinor);
       
       if(theErr && *theErr < 0)
         return;
@@ -247,7 +252,7 @@ namespace MED
                   EModeAcces theMode,
                   TErr* theErr)
     {
-      TFileWrapper aFileWrapper(myFile,theMode,theErr);
+      TFileWrapper aFileWrapper(myFile,theMode,theErr, myMinor);
       
       if(theErr && *theErr < 0)
         return;
@@ -316,7 +321,7 @@ namespace MED
     ::GetNbFamilies(const MED::TMeshInfo& theInfo,
                     TErr* theErr)
     {
-      TFileWrapper aFileWrapper(myFile,eLECTURE,theErr);
+      TFileWrapper aFileWrapper(myFile,eLECTURE,theErr, myMinor);
       
       if(theErr && *theErr < 0)
         return -1;
@@ -334,7 +339,7 @@ namespace MED
                    const MED::TMeshInfo& theInfo,
                    TErr* theErr)
     {
-      TFileWrapper aFileWrapper(myFile,eLECTURE,theErr);
+      TFileWrapper aFileWrapper(myFile,eLECTURE,theErr, myMinor);
       
       if(theErr && *theErr < 0)
         return -1;
@@ -354,7 +359,7 @@ namespace MED
                     const MED::TMeshInfo& theInfo,
                     TErr* theErr)
     {
-      TFileWrapper aFileWrapper(myFile,eLECTURE,theErr);
+      TFileWrapper aFileWrapper(myFile,eLECTURE,theErr, myMinor);
       
       if(theErr && *theErr < 0)
         return -1;
@@ -374,7 +379,7 @@ namespace MED
                     MED::TFamilyInfo& theInfo,
                     TErr* theErr)
     {
-      TFileWrapper aFileWrapper(myFile,eLECTURE,theErr);
+      TFileWrapper aFileWrapper(myFile,eLECTURE,theErr, myMinor);
       
       if(theErr && *theErr < 0)
         return;
@@ -417,7 +422,7 @@ namespace MED
                     EModeAcces theMode,
                     TErr* theErr)
     {
-      TFileWrapper aFileWrapper(myFile,theMode,theErr);
+      TFileWrapper aFileWrapper(myFile,theMode,theErr, myMinor);
       
       if(theErr && *theErr < 0)
         return;
@@ -476,7 +481,7 @@ namespace MED
                EGeometrieElement theGeom,
                TErr*             theErr)
     {
-      TFileWrapper aFileWrapper(myFile,eLECTURE,theErr);
+      TFileWrapper aFileWrapper(myFile,eLECTURE,theErr, myMinor);
       
       if(theErr && *theErr < 0)
         return;
@@ -514,7 +519,7 @@ namespace MED
                     EGeometrieElement theGeom,
                     TErr*             theErr)
     {
-      TFileWrapper aFileWrapper(myFile,eLECTURE,theErr);
+      TFileWrapper aFileWrapper(myFile,eLECTURE,theErr, myMinor);
       
       if(theErr && *theErr < 0)
         return;
@@ -552,7 +557,7 @@ namespace MED
                   EGeometrieElement theGeom,
                   TErr*             theErr)
     {
-      TFileWrapper aFileWrapper(myFile,eLECTURE,theErr);
+      TFileWrapper aFileWrapper(myFile,eLECTURE,theErr, myMinor);
       
       if(theErr && *theErr < 0)
         return;
@@ -613,7 +618,7 @@ namespace MED
                EGeometrieElement theGeom,
                TErr*             theErr)
     {
-      TFileWrapper aFileWrapper(myFile,theMode,theErr);
+      TFileWrapper aFileWrapper(myFile,theMode,theErr, myMinor);
       
       if(theErr && *theErr < 0)
         return;
@@ -669,7 +674,7 @@ namespace MED
                     EGeometrieElement theGeom,
                     TErr*             theErr)
     {
-      TFileWrapper aFileWrapper(myFile,theMode,theErr);
+      TFileWrapper aFileWrapper(myFile,theMode,theErr, myMinor);
       
       if(theErr && *theErr < 0)
         return;
@@ -723,7 +728,7 @@ namespace MED
                   EGeometrieElement theGeom,
                   TErr*             theErr)
     {
-      TFileWrapper aFileWrapper(myFile,theMode,theErr);
+      TFileWrapper aFileWrapper(myFile,theMode,theErr, myMinor);
       
       if(theErr && *theErr < 0)
         return;
@@ -761,7 +766,7 @@ namespace MED
                  ETable theTable,
                  TErr* theErr)
     {
-      TFileWrapper aFileWrapper(myFile,eLECTURE,theErr);
+      TFileWrapper aFileWrapper(myFile,eLECTURE,theErr, myMinor);
       
       if(theErr && *theErr < 0)
         return -1;
@@ -790,7 +795,7 @@ namespace MED
     ::GetNodeInfo(MED::TNodeInfo& theInfo,
                   TErr* theErr)
     {
-      TFileWrapper aFileWrapper(myFile,eLECTURE,theErr);
+      TFileWrapper aFileWrapper(myFile,eLECTURE,theErr, myMinor);
       
       if(theErr && *theErr < 0)
         return;
@@ -867,7 +872,7 @@ namespace MED
                   EModeAcces theMode,
                   TErr* theErr)
     {
-      TFileWrapper aFileWrapper(myFile,theMode,theErr);
+      TFileWrapper aFileWrapper(myFile,theMode,theErr, myMinor);
       
       if(theErr && *theErr < 0)
         return;
@@ -953,7 +958,7 @@ namespace MED
     ::GetPolygoneInfo(MED::TPolygoneInfo& theInfo,
                       TErr* theErr)
     {
-      TFileWrapper aFileWrapper(myFile,eLECTURE,theErr);
+      TFileWrapper aFileWrapper(myFile,eLECTURE,theErr, myMinor);
 
       if(theErr && *theErr < 0)
         return;
@@ -1012,7 +1017,7 @@ namespace MED
                       EModeAcces theMode,
                       TErr* theErr)
     {
-      TFileWrapper aFileWrapper(myFile,theMode,theErr);
+      TFileWrapper aFileWrapper(myFile,theMode,theErr, myMinor);
       
       if(theErr && *theErr < 0)
         return;
@@ -1071,7 +1076,7 @@ namespace MED
                           EConnectivite theConnMode,
                           TErr* theErr)
     {
-      TFileWrapper aFileWrapper(myFile,eLECTURE,theErr);
+      TFileWrapper aFileWrapper(myFile,eLECTURE,theErr, myMinor);
 
       if(theErr && *theErr < 0)
         return 0;
@@ -1105,7 +1110,7 @@ namespace MED
     ::GetPolyedreInfo(TPolyedreInfo& theInfo,
                       TErr* theErr)
     {
-      TFileWrapper aFileWrapper(myFile,eLECTURE,theErr);
+      TFileWrapper aFileWrapper(myFile,eLECTURE,theErr, myMinor);
 
       if(theErr && *theErr < 0)
         return;
@@ -1168,7 +1173,7 @@ namespace MED
                       EModeAcces theMode,
                       TErr* theErr)
     {
-      TFileWrapper aFileWrapper(myFile,theMode,theErr);
+      TFileWrapper aFileWrapper(myFile,theMode,theErr, myMinor);
       
       if(theErr && *theErr < 0)
         return;
@@ -1272,7 +1277,7 @@ namespace MED
                           EConnectivite theConnMode,
                           TErr* theErr)
     {
-      TFileWrapper aFileWrapper(myFile,eLECTURE,theErr);
+      TFileWrapper aFileWrapper(myFile,eLECTURE,theErr, myMinor);
 
       if(theErr && *theErr < 0) 
         EXCEPTION(std::runtime_error,"GetPolyedreConnSize - (...)");
@@ -1321,7 +1326,7 @@ namespace MED
     {
       TEntityInfo anInfo;
       
-      TFileWrapper aFileWrapper(myFile,eLECTURE,theErr);
+      TFileWrapper aFileWrapper(myFile,eLECTURE,theErr, myMinor);
       
       if(theErr && *theErr < 0)
         return anInfo;
@@ -1431,7 +1436,7 @@ namespace MED
                                EConnectivite theConnMode,
                                TErr* theErr)
     {
-      TFileWrapper aFileWrapper(myFile,eLECTURE,theErr);
+      TFileWrapper aFileWrapper(myFile,eLECTURE,theErr, myMinor);
 
       if(theErr && *theErr < 0)
         return -1;
@@ -1478,7 +1483,7 @@ namespace MED
     //----------------------------------------------------------------------------
     void TVWrapper::GetCellInfo(MED::TCellInfo& theInfo, TErr* theErr)
     {
-      TFileWrapper aFileWrapper(myFile,eLECTURE,theErr);
+      TFileWrapper aFileWrapper(myFile,eLECTURE,theErr, myMinor);
 
       if(theErr && *theErr < 0)
         return;
@@ -1537,7 +1542,7 @@ namespace MED
                   EModeAcces theMode,
                   TErr* theErr)
     {
-      TFileWrapper aFileWrapper(myFile,theMode,theErr);
+      TFileWrapper aFileWrapper(myFile,theMode,theErr, myMinor);
       
       if(theErr && *theErr < 0)
         return;
@@ -1618,7 +1623,8 @@ namespace MED
     //! Read geom type of MED_BALL structural element
     EGeometrieElement TVWrapper::GetBallGeom(const TMeshInfo& theMeshInfo)
     {
-      TFileWrapper aFileWrapper(myFile,eLECTURE);
+      TErr anError;
+      TFileWrapper aFileWrapper(myFile, eLECTURE, &anError, myMinor);
 
       // read med_geometry_type of "MED_BALL" element
       char geotypename[ MED_NAME_SIZE + 1] = MED_BALL_NAME;
@@ -1629,7 +1635,8 @@ namespace MED
     //! Read number of balls in the Mesh
     TInt TVWrapper::GetNbBalls(const TMeshInfo& theMeshInfo)
     {
-      TFileWrapper aFileWrapper(myFile,eLECTURE);
+      TErr anError;
+      TFileWrapper aFileWrapper(myFile, eLECTURE, &anError, myMinor);
 
       EGeometrieElement ballType = GetBallGeom( theMeshInfo );
       if ( ballType < 0 )
@@ -1642,7 +1649,7 @@ namespace MED
     //! Read a MEDWrapped representation of MED_BALL from the MED file
     void TVWrapper::GetBallInfo(TBallInfo& theInfo, TErr* theErr)
     {
-      TFileWrapper aFileWrapper(myFile,eLECTURE,theErr);
+      TFileWrapper aFileWrapper(myFile,eLECTURE,theErr, myMinor);
 
       // check geometry of MED_BALL
       if ( theInfo.myGeom == eBALL )
@@ -1681,7 +1688,7 @@ namespace MED
     //! Write a MEDWrapped representation of MED_BALL to the MED file
     void  TVWrapper::SetBallInfo(const TBallInfo& theInfo, EModeAcces theMode, TErr* theErr)
     {
-      TFileWrapper aFileWrapper(myFile,theMode,theErr);
+      TFileWrapper aFileWrapper(myFile,theMode,theErr, myMinor);
 
       TErr ret;
       char ballsupportname[MED_NAME_SIZE+1]="BALL_SUPPORT_MESH";
@@ -1769,7 +1776,7 @@ namespace MED
     TVWrapper
     ::GetNbFields(TErr* theErr)
     {
-      TFileWrapper aFileWrapper(myFile,eLECTURE,theErr);
+      TFileWrapper aFileWrapper(myFile,eLECTURE,theErr, myMinor);
       
       if(theErr && *theErr < 0)
         return -1;
@@ -1784,7 +1791,7 @@ namespace MED
     ::GetNbComp(TInt theFieldId,
                 TErr* theErr)
     {
-      TFileWrapper aFileWrapper(myFile,eLECTURE,theErr);
+      TFileWrapper aFileWrapper(myFile,eLECTURE,theErr, myMinor);
       
       if(theErr && *theErr < 0)
         return -1;
@@ -1800,7 +1807,7 @@ namespace MED
                    MED::TFieldInfo& theInfo,
                    TErr* theErr)
     {
-      TFileWrapper aFileWrapper(myFile,eLECTURE,theErr);
+      TFileWrapper aFileWrapper(myFile,eLECTURE,theErr, myMinor);
       
       if(theErr && *theErr < 0)
         return;
@@ -1850,7 +1857,7 @@ namespace MED
                    EModeAcces theMode,
                    TErr* theErr)
     {
-      TFileWrapper aFileWrapper(myFile,theMode,theErr);
+      TFileWrapper aFileWrapper(myFile,theMode,theErr, myMinor);
       
       if(theErr && *theErr < 0)
         return;
@@ -1902,7 +1909,7 @@ namespace MED
     TVWrapper
     ::GetNbGauss(TErr* theErr)
     {
-      TFileWrapper aFileWrapper(myFile,eLECTURE,theErr);
+      TFileWrapper aFileWrapper(myFile,eLECTURE,theErr, myMinor);
       
       if(theErr && *theErr < 0)
         return -1;
@@ -1917,7 +1924,7 @@ namespace MED
     ::GetGaussPreInfo(TInt theId, 
                       TErr* theErr)
     {
-      TFileWrapper aFileWrapper(myFile,eLECTURE,theErr);
+      TFileWrapper aFileWrapper(myFile,eLECTURE,theErr, myMinor);
 
       if(theErr && *theErr < 0)
         return TGaussInfo::TInfo( TGaussInfo::TKey(ePOINT1,""),0 );
@@ -1958,7 +1965,7 @@ namespace MED
                    TGaussInfo& theInfo,
                    TErr* theErr)
     {
-      TFileWrapper aFileWrapper(myFile,eLECTURE,theErr);
+      TFileWrapper aFileWrapper(myFile,eLECTURE,theErr, myMinor);
       
       if(theErr && *theErr < 0)
         return;
@@ -1989,7 +1996,7 @@ namespace MED
     TVWrapper
     ::GetNbProfiles(TErr* theErr)
     {
-      TFileWrapper aFileWrapper(myFile,eLECTURE,theErr);
+      TFileWrapper aFileWrapper(myFile,eLECTURE,theErr, myMinor);
       
       if(theErr && *theErr < 0)
         return -1;
@@ -2002,7 +2009,7 @@ namespace MED
     ::GetProfilePreInfo(TInt theId, 
                         TErr* theErr)
     {
-      TFileWrapper aFileWrapper(myFile,eLECTURE,theErr);
+      TFileWrapper aFileWrapper(myFile,eLECTURE,theErr, myMinor);
 
       if(theErr && *theErr < 0)
         return TProfileInfo::TInfo();
@@ -2029,7 +2036,7 @@ namespace MED
                      TProfileInfo& theInfo,
                      TErr* theErr)
     {
-      TFileWrapper aFileWrapper(myFile,eLECTURE,theErr);
+      TFileWrapper aFileWrapper(myFile,eLECTURE,theErr, myMinor);
       
       if(theErr && *theErr < 0)
         return;
@@ -2054,7 +2061,7 @@ namespace MED
                      EModeAcces          theMode,
                      TErr*               theErr)
     {
-      TFileWrapper aFileWrapper(myFile,theMode,theErr);
+      TFileWrapper aFileWrapper(myFile,theMode,theErr, myMinor);
       
       if(theErr && *theErr < 0)
         return;
@@ -2102,7 +2109,7 @@ namespace MED
                       TErr* theErr)
     {
       theEntity = EEntiteMaillage(-1);
-      TFileWrapper aFileWrapper(myFile,eLECTURE,theErr);
+      TFileWrapper aFileWrapper(myFile,eLECTURE,theErr, myMinor);
 
       if(theErr){
         if(theEntityInfo.empty())
@@ -2225,7 +2232,7 @@ namespace MED
                        MED::TTimeStampInfo& theInfo,
                        TErr* theErr)
     {
-      TFileWrapper aFileWrapper(myFile,eLECTURE,theErr);
+      TFileWrapper aFileWrapper(myFile,eLECTURE,theErr, myMinor);
       
       const TGeom2Size& aGeom2Size = theInfo.myGeom2Size;
       
@@ -2320,7 +2327,7 @@ namespace MED
                         const TKey2Gauss& theKey2Gauss,
                         TErr* theErr)
     {
-      TFileWrapper aFileWrapper(myFile,eLECTURE,theErr);
+      TFileWrapper aFileWrapper(myFile,eLECTURE,theErr, myMinor);
       
       if(theErr && *theErr < 0)
         return;
@@ -2488,7 +2495,7 @@ namespace MED
                         EModeAcces theMode,
                         TErr* theErr)
     {
-      TFileWrapper aFileWrapper(myFile,theMode,theErr);
+      TFileWrapper aFileWrapper(myFile,theMode,theErr, myMinor);
       
       if(theErr && *theErr < 0)
         return;
@@ -2598,7 +2605,7 @@ namespace MED
     {
       if(theInfo.myMeshInfo->myType != eSTRUCTURE)
         return;
-      TFileWrapper aFileWrapper(myFile,theMode,theErr);
+      TFileWrapper aFileWrapper(myFile,theMode,theErr, myMinor);
       
       if(theErr && *theErr < 0)
           return;
@@ -2675,7 +2682,7 @@ namespace MED
     ::GetGrilleInfo(TGrilleInfo& theInfo,
                     TErr* theErr)
     {
-      TFileWrapper aFileWrapper(myFile,eLECTURE,theErr);
+      TFileWrapper aFileWrapper(myFile,eLECTURE,theErr, myMinor);
 
       if(theErr && *theErr < 0)
           return;
@@ -2831,7 +2838,7 @@ namespace MED
                     EGrilleType& theGridType,
                     TErr* theErr)
     {
-      TFileWrapper aFileWrapper(myFile,eLECTURE,theErr);
+      TFileWrapper aFileWrapper(myFile,eLECTURE,theErr, myMinor);
 
       if(theErr && *theErr < 0)
         EXCEPTION(std::runtime_error," GetGrilleType - aFileWrapper (...)");
@@ -2856,7 +2863,7 @@ namespace MED
                       TIntVector& theStruct,
                       TErr* theErr)
     {
-      TFileWrapper aFileWrapper(myFile,eLECTURE,theErr);
+      TFileWrapper aFileWrapper(myFile,eLECTURE,theErr, myMinor);
       
       if(theErr && *theErr < 0)
           return;
index a06e1c15c08278e34f559b87a3eb98690b48ea98..45f9a14a55e43c917c5e2846da39cc5f470b0bdc 100644 (file)
@@ -91,7 +91,7 @@ namespace MED
       TVWrapper& operator=(const TVWrapper&);
       
     public:
-      TVWrapper(const std::string& theFileName);
+      TVWrapper(const std::string& theFileName, TInt theMinor=-1);
 
       //----------------------------------------------------------------------------
       virtual 
@@ -482,6 +482,7 @@ namespace MED
 
     protected:
       PFile myFile;
+      TInt myMinor;
     };
   }
 }
index 43e4bca326bbb20bca69a07c2da16599f7bf9e79..48ad71c59cebebd0e143981c170ac47fb84ebb44 100644 (file)
@@ -279,6 +279,7 @@ SMESH_ActorDef::SMESH_ActorDef()
   aFilter->RegisterCellsWithType(VTK_QUADRATIC_HEXAHEDRON);
   aFilter->RegisterCellsWithType(VTK_TRIQUADRATIC_HEXAHEDRON);
   aFilter->RegisterCellsWithType(VTK_QUADRATIC_WEDGE);
+  aFilter->RegisterCellsWithType(VTK_BIQUADRATIC_QUADRATIC_WEDGE);
   aFilter->RegisterCellsWithType(VTK_QUADRATIC_PYRAMID);
   aFilter->RegisterCellsWithType(VTK_CONVEX_POINT_SET);
   aFilter->RegisterCellsWithType(VTK_POLYHEDRON);
@@ -310,6 +311,7 @@ SMESH_ActorDef::SMESH_ActorDef()
   aFilter->RegisterCellsWithType(VTK_QUADRATIC_HEXAHEDRON);
   aFilter->RegisterCellsWithType(VTK_TRIQUADRATIC_HEXAHEDRON);
   aFilter->RegisterCellsWithType(VTK_QUADRATIC_WEDGE);
+  aFilter->RegisterCellsWithType(VTK_BIQUADRATIC_QUADRATIC_WEDGE);
   aFilter->RegisterCellsWithType(VTK_QUADRATIC_PYRAMID);
   aFilter->RegisterCellsWithType(VTK_CONVEX_POINT_SET);
   aFilter->RegisterCellsWithType(VTK_POLYHEDRON);
@@ -1683,6 +1685,7 @@ void SMESH_ActorDef::SetEntityMode(unsigned int theMode)
         aFilter->RegisterCellsWithType(VTK_TRIQUADRATIC_HEXAHEDRON);
         aFilter->RegisterCellsWithType(VTK_QUADRATIC_PYRAMID);
         aFilter->RegisterCellsWithType(VTK_QUADRATIC_WEDGE);
+        aFilter->RegisterCellsWithType(VTK_BIQUADRATIC_QUADRATIC_WEDGE);
         aFilter->RegisterCellsWithType(VTK_CONVEX_POINT_SET);
         aFilter->RegisterCellsWithType(VTK_POLYHEDRON);
 
@@ -1696,6 +1699,7 @@ void SMESH_ActorDef::SetEntityMode(unsigned int theMode)
         aHltFilter->RegisterCellsWithType(VTK_QUADRATIC_HEXAHEDRON);
         aHltFilter->RegisterCellsWithType(VTK_TRIQUADRATIC_HEXAHEDRON);
         aHltFilter->RegisterCellsWithType(VTK_QUADRATIC_WEDGE);
+        aHltFilter->RegisterCellsWithType(VTK_BIQUADRATIC_QUADRATIC_WEDGE);
         aHltFilter->RegisterCellsWithType(VTK_QUADRATIC_PYRAMID);
         aHltFilter->RegisterCellsWithType(VTK_CONVEX_POINT_SET);
         aHltFilter->RegisterCellsWithType(VTK_POLYHEDRON);
index 2f6ccd06f0044e7a26e03d7b5a87c80db50f26f9..cfe6159a2c0e7e4484c444878060473940d275f2 100644 (file)
@@ -37,6 +37,7 @@
 #include <VTKViewer_Transform.h>
 #include <VTKViewer_TransformFilter.h>
 #include <VTKViewer_ExtractUnstructuredGrid.h>
+#include <VTKViewer_Actor.h>
 
 // VTK Includes
 #include <vtkObjectFactory.h>
@@ -94,8 +95,8 @@ SMESH_DeviceActor
   myMapper = VTKViewer_PolyDataMapper::New();
   myPlaneCollection = vtkPlaneCollection::New();
 
-  vtkMapper::GetResolveCoincidentTopologyPolygonOffsetParameters(myPolygonOffsetFactor,
-                                                                 myPolygonOffsetUnits);
+  VTKViewer_Actor::GetDefaultPolygonOffsetParameters(myPolygonOffsetFactor,
+                                                     myPolygonOffsetUnits);
 
   myMapper->UseLookupTableScalarRangeOn();
   myMapper->SetColorModeToMapScalars();
index a45696d7e9a4e6059276eb03d76a41930f92f374..8096b1609fbc22ee5829b729af09cd414f5f4c56 100644 (file)
 
 #include <vtkCellArray.h>
 #include <vtkCellData.h>
+#include <vtkLookupTable.h>
 #include <vtkObjectFactory.h>
 #include <vtkPolyData.h>
 #include <vtkPolyDataMapper2D.h>
+#include <vtkProperty2D.h>
 #include <vtkScalarsToColors.h>
 #include <vtkTextMapper.h>
 #include <vtkTextProperty.h>
 #include <vtkViewport.h>
 #include <vtkWindow.h>
-#include <vtkLookupTable.h>
-#include <vtkProperty2D.h>
 
 #define SHRINK_COEF 0.08;
 
@@ -51,13 +51,14 @@ vtkCxxSetObjectMacro(SMESH_ScalarBarActor,TitleTextProperty,vtkTextProperty);
 // Instantiate object with 64 maximum colors; 5 labels; %%-#6.3g label
 // format, no title, and vertical orientation. The initial scalar bar
 // size is (0.05 x 0.8) of the viewport size.
-SMESH_ScalarBarActor::SMESH_ScalarBarActor() {
+SMESH_ScalarBarActor::SMESH_ScalarBarActor()
+{
   this->LookupTable = NULL;
   this->Position2Coordinate->SetValue(0.17, 0.8);
-  
+
   this->PositionCoordinate->SetCoordinateSystemToNormalizedViewport();
   this->PositionCoordinate->SetValue(0.82,0.1);
-  
+
   this->MaximumNumberOfColors = 64;
   this->NumberOfLabels = 5;
   this->NumberOfLabelsBuilt = 0;
@@ -74,7 +75,7 @@ SMESH_ScalarBarActor::SMESH_ScalarBarActor() {
   this->TitleTextProperty = vtkTextProperty::New();
   this->TitleTextProperty->ShallowCopy(this->LabelTextProperty);
 
-  this->LabelFormat = new char[8]; 
+  this->LabelFormat = new char[8];
   sprintf(this->LabelFormat,"%s","%-#6.3g");
 
   this->TitleMapper = vtkTextMapper::New();
@@ -82,7 +83,7 @@ SMESH_ScalarBarActor::SMESH_ScalarBarActor() {
   this->TitleActor->SetMapper(this->TitleMapper);
   this->TitleActor->GetPositionCoordinate()->
     SetReferenceCoordinate(this->PositionCoordinate);
-  
+
   this->TextMappers = NULL;
   this->TextActors = NULL;
 
@@ -104,7 +105,7 @@ SMESH_ScalarBarActor::SMESH_ScalarBarActor() {
   myDistribution = vtkPolyData::New();
   myDistributionMapper = vtkPolyDataMapper2D::New();
   myDistributionMapper->SetInputData(this->myDistribution);
-  
+
   myDistributionActor = vtkActor2D::New();
   myDistributionActor->SetMapper(this->myDistributionMapper);
   myDistributionActor->GetPositionCoordinate()->
@@ -129,12 +130,12 @@ void SMESH_ScalarBarActor::ReleaseGraphicsResources(vtkWindow *win)
 {
   this->TitleActor->ReleaseGraphicsResources(win);
   if (this->TextMappers != NULL )
-    {
+  {
     for (int i=0; i < this->NumberOfLabelsBuilt; i++)
-      {
+    {
       this->TextActors[i]->ReleaseGraphicsResources(win);
-      }
     }
+  }
   this->ScalarBarActor->ReleaseGraphicsResources(win);
   // rnv begin
   // Customization of the vtkScalarBarActor to show distribution histogram.
@@ -143,41 +144,42 @@ void SMESH_ScalarBarActor::ReleaseGraphicsResources(vtkWindow *win)
 
 
 /*--------------------------------------------------------------------------*/
-SMESH_ScalarBarActor::~SMESH_ScalarBarActor() {
-  if (this->LabelFormat) 
-    {
+SMESH_ScalarBarActor::~SMESH_ScalarBarActor()
+{
+  if (this->LabelFormat)
+  {
     delete [] this->LabelFormat;
     this->LabelFormat = NULL;
-    }
+  }
 
   this->TitleMapper->Delete();
   this->TitleActor->Delete();
 
   if (this->TextMappers != NULL )
-    {
+  {
     for (int i=0; i < this->NumberOfLabelsBuilt; i++)
-      {
+    {
       this->TextMappers[i]->Delete();
       this->TextActors[i]->Delete();
-      }
+    }
     delete [] this->TextMappers;
     delete [] this->TextActors;
-    }
+  }
 
   this->ScalarBar->Delete();
   this->ScalarBarMapper->Delete();
   this->ScalarBarActor->Delete();
 
   if (this->Title)
-    {
+  {
     delete [] this->Title;
     this->Title = NULL;
-    }
-  
+  }
+
   this->SetLookupTable(NULL);
   this->SetLabelTextProperty(NULL);
   this->SetTitleTextProperty(NULL);
-  
+
   // rnv begin
   // Customization of the vtkScalarBarActor to show distribution histogram:
   myDistribution->Delete();
@@ -191,26 +193,26 @@ int SMESH_ScalarBarActor::RenderOverlay(vtkViewport *viewport)
 {
   int renderedSomething = 0;
   int i;
-  
+
   // Everything is built, just have to render
   if (this->Title != NULL)
-    {
+  {
     renderedSomething += this->TitleActor->RenderOverlay(viewport);
-    }
-  if (!myTitleOnlyVisibility) {
+  }
+  if ( !myTitleOnlyVisibility ) {
     this->ScalarBarActor->RenderOverlay(viewport);
     this->myDistributionActor->RenderOverlay(viewport);
-    if( this->TextActors == NULL)
-      {
-       vtkWarningMacro(<<"Need a mapper to render a scalar bar");
-       return renderedSomething;
-      }
-  
-    for (i=0; i<this->NumberOfLabels; i++)
-      {
+    if ( this->TextActors == NULL )
+    {
+      vtkWarningMacro(<<"Need a mapper to render a scalar bar");
+      return renderedSomething;
+    }
+
+    for ( i=0; i<this->NumberOfLabels; i++ )
+    {
       renderedSomething += this->TextActors[i]->RenderOverlay(viewport);
-      }
-  }  
+    }
+  }
   renderedSomething = (renderedSomething > 0)?(1):(0);
 
   return renderedSomething;
@@ -223,75 +225,75 @@ int SMESH_ScalarBarActor::RenderOpaqueGeometry(vtkViewport *viewport)
   int renderedSomething = 0;
   int i;
   int size[2];
-  
+
   if (!this->LookupTable)
-    {
+  {
     vtkWarningMacro(<<"Need a mapper to render a scalar bar");
     return 0;
-    }
+  }
 
   if (!this->TitleTextProperty)
-    {
+  {
     vtkErrorMacro(<<"Need title text property to render a scalar bar");
     return 0;
-    }
+  }
 
   if (!this->LabelTextProperty)
-    {
+  {
     vtkErrorMacro(<<"Need label text property to render a scalar bar");
     return 0;
-    }
+  }
 
   // Check to see whether we have to rebuild everything
   int positionsHaveChanged = 0;
-  if (viewport->GetMTime() > this->BuildTime || 
-      (viewport->GetVTKWindow() && 
+  if (viewport->GetMTime() > this->BuildTime ||
+      (viewport->GetVTKWindow() &&
        viewport->GetVTKWindow()->GetMTime() > this->BuildTime))
-    {
+  {
     // if the viewport has changed we may - or may not need
     // to rebuild, it depends on if the projected coords chage
     int *barOrigin;
     barOrigin = this->PositionCoordinate->GetComputedViewportValue(viewport);
-    size[0] = 
+    size[0] =
       this->Position2Coordinate->GetComputedViewportValue(viewport)[0] -
       barOrigin[0];
-    size[1] = 
+    size[1] =
       this->Position2Coordinate->GetComputedViewportValue(viewport)[1] -
       barOrigin[1];
-    if (this->LastSize[0] != size[0] || 
+    if (this->LastSize[0] != size[0] ||
         this->LastSize[1] != size[1] ||
-        this->LastOrigin[0] != barOrigin[0] || 
+        this->LastOrigin[0] != barOrigin[0] ||
         this->LastOrigin[1] != barOrigin[1])
-      {
+    {
       positionsHaveChanged = 1;
-      }
     }
-  
+  }
+
   // Check to see whether we have to rebuild everything
-  if (positionsHaveChanged ||
-      this->GetMTime() > this->BuildTime || 
-      this->LookupTable->GetMTime() > this->BuildTime ||
-      this->LabelTextProperty->GetMTime() > this->BuildTime ||
-      this->TitleTextProperty->GetMTime() > this->BuildTime)
-    {
+  if ( positionsHaveChanged ||
+       this->GetMTime() > this->BuildTime ||
+       this->LookupTable->GetMTime() > this->BuildTime ||
+       this->LabelTextProperty->GetMTime() > this->BuildTime ||
+       this->TitleTextProperty->GetMTime() > this->BuildTime)
+  {
     vtkDebugMacro(<<"Rebuilding subobjects");
 
     // Delete previously constructed objects
     //
-    if (this->TextMappers != NULL )
+    if ( this->TextMappers != NULL )
+    {
+      for ( i = 0; i < this->NumberOfLabelsBuilt; i++ )
       {
-      for (i=0; i < this->NumberOfLabelsBuilt; i++)
-        {
         this->TextMappers[i]->Delete();
         this->TextActors[i]->Delete();
-        }
+      }
       delete [] this->TextMappers;
       delete [] this->TextActors;
-      }
+    }
 
     // Build scalar bar object; determine its type
     //
-    // is this a vtkLookupTable or a subclass of vtkLookupTable 
+    // is this a vtkLookupTable or a subclass of vtkLookupTable
     // with its scale set to log
     // NOTE: it's possible we could to without the 'lut' variable
     // later in the code, but if the vtkLookupTableSafeDownCast operation
@@ -300,13 +302,13 @@ int SMESH_ScalarBarActor::RenderOpaqueGeometry(vtkViewport *viewport)
     vtkLookupTable *LUT = vtkLookupTable::SafeDownCast( this->LookupTable );
     int isLogTable = 0;
     if ( LUT )
-      {
+    {
       if ( LUT->GetScale() == VTK_SCALE_LOG10 )
-        {
-        isLogTable = 1; 
-        }
+      {
+        isLogTable = 1;
       }
-    
+    }
+
     // we hard code how many steps to display
     vtkScalarsToColors *lut = this->LookupTable;
     int numColors = this->MaximumNumberOfColors;
@@ -332,7 +334,8 @@ int SMESH_ScalarBarActor::RenderOpaqueGeometry(vtkViewport *viewport)
     if(!distrVisibility)
       vtkDebugMacro(<<" Distribution invisible, because numColors == this->myNbValues.size()");
 
-    if ( distrVisibility && GetDistributionVisibility() ) {
+    if ( distrVisibility && GetDistributionVisibility() )
+    {
       for ( i = 0 ; i < (int)myNbValues.size(); i++ ) {
         if ( myNbValues[i] ) {
           numPositiveVal++;
@@ -349,16 +352,21 @@ int SMESH_ScalarBarActor::RenderOpaqueGeometry(vtkViewport *viewport)
       this->myDistribution->SetPolys(distrPolys);
       distrPts->Delete();
       distrPolys->Delete();
-      if ( myDistributionColoringType == SMESH_MULTICOLOR_TYPE ) {
+      if ( myDistributionColoringType == SMESH_MULTICOLOR_TYPE )
+      {
         distColors = vtkUnsignedCharArray::New();
         distColors->SetNumberOfComponents(3);
         distColors->SetNumberOfTuples(numPositiveVal);
         this->myDistribution->GetCellData()->SetScalars(distColors);
         distColors->Delete();
-      } else if( myDistributionColoringType == SMESH_MONOCOLOR_TYPE ){
+      }
+      else if( myDistributionColoringType == SMESH_MONOCOLOR_TYPE )
+      {
         this->myDistribution->GetCellData()->SetScalars(NULL);
       }
-    } else {
+    }
+    else
+    {
       myDistribution->Reset();
     }
     // rnv end
@@ -373,22 +381,22 @@ int SMESH_ScalarBarActor::RenderOpaqueGeometry(vtkViewport *viewport)
     // get the viewport size in display coordinates
     int *barOrigin, barWidth, barHeight, distrHeight;
     barOrigin = this->PositionCoordinate->GetComputedViewportValue(viewport);
-    size[0] = 
+    size[0] =
       this->Position2Coordinate->GetComputedViewportValue(viewport)[0] -
       barOrigin[0];
-    size[1] = 
+    size[1] =
       this->Position2Coordinate->GetComputedViewportValue(viewport)[1] -
       barOrigin[1];
     this->LastOrigin[0] = barOrigin[0];
     this->LastOrigin[1] = barOrigin[1];
     this->LastSize[0] = size[0];
     this->LastSize[1] = size[1];
-    
+
     // Update all the composing objects
     this->TitleActor->SetProperty(this->GetProperty());
     this->TitleMapper->SetInput(this->Title);
     if (this->TitleTextProperty->GetMTime() > this->BuildTime)
-      {
+    {
       // Shallow copy here so that the size of the title prop is not affected
       // by the automatic adjustment of its text mapper's size (i.e. its
       // mapper's text property is identical except for the font size
@@ -397,17 +405,17 @@ int SMESH_ScalarBarActor::RenderOpaqueGeometry(vtkViewport *viewport)
       // the title and label text prop to be the same.
       this->TitleMapper->GetTextProperty()->ShallowCopy(this->TitleTextProperty);
       this->TitleMapper->GetTextProperty()->SetJustificationToCentered();
-      }
-    
+    }
+
     // find the best size for the title font
     int titleSize[2];
     this->SizeTitle(titleSize, size, viewport);
-    
+
     // find the best size for the ticks
     int labelSize[2];
     this->AllocateAndSizeLabels(labelSize, size, viewport,range);
     this->NumberOfLabelsBuilt = this->NumberOfLabels;
-    
+
     // generate points
     double x[3]; x[2] = 0.0;
     double delta, itemH, shrink;
@@ -426,7 +434,7 @@ int SMESH_ScalarBarActor::RenderOpaqueGeometry(vtkViewport *viewport)
 
       barHeight = (int)(0.86*size[1]);
       delta=(double)barHeight/numColors;
-      
+
       for ( i=0; i<numPts/2; i++ ) {
         x[0] = distrHeight+delimeter/2.0;
         x[1] = i*delta;
@@ -435,22 +443,22 @@ int SMESH_ScalarBarActor::RenderOpaqueGeometry(vtkViewport *viewport)
         pts->SetPoint(2*i+1,x);
       }
 
-      if(GetDistributionVisibility() && distrVisibility) {
-        // Distribution points 
+      if ( GetDistributionVisibility() && distrVisibility ) {
+        // Distribution points
         shrink = delta*SHRINK_COEF;
         vtkIdType distPtsId=0;
         vtkIdType distPtsIds[4];
-        for(i=0; i<numColors; i++) {
-          if(myNbValues[i]) {
+        for ( i = 0; i < numColors; i++ ) {
+          if ( myNbValues[i] ) {
             itemH = distrHeight*((double)myNbValues[i]/maxValue);
-            
-            if(distrHeight == itemH) 
+
+            if(distrHeight == itemH)
               itemH = itemH - delimeter/2;
 
             x[1] = i*delta+shrink;
 
             // first point of polygon (quadrangle)
-            x[0] = 0; 
+            x[0] = 0;
             distPtsIds[0] = distPtsId;
             distrPts->SetPoint(distPtsId++,x);
 
@@ -462,7 +470,7 @@ int SMESH_ScalarBarActor::RenderOpaqueGeometry(vtkViewport *viewport)
             x[1] = i*delta+delta-shrink;
 
             // third point of polygon (quadrangle)
-            x[0] = 0; 
+            x[0] = 0;
             distPtsIds[3] = distPtsId;
             distrPts->SetPoint(distPtsId++,x);
 
@@ -475,19 +483,19 @@ int SMESH_ScalarBarActor::RenderOpaqueGeometry(vtkViewport *viewport)
             distrPolys->InsertNextCell(4,distPtsIds);
           }
         }
-      }    
+      }
     }
     // rnv end
     else {
       barWidth = size[0];
-      
+
       // rnv begin
       // Customization of the vtkScalarBarActor to show distribution histogram.
       double coef1, delimeter=0.0;
-      if(GetDistributionVisibility() && distrVisibility) {
+      if ( GetDistributionVisibility() && distrVisibility ) {
         coef1=0.62;
         distrHeight = (int)((coef1/2)*size[1]);
-        //delimeter between distribution diagram and scalar bar 
+        //delimeter between distribution diagram and scalar bar
         delimeter=0.02*size[1];
       }
       else {
@@ -495,64 +503,64 @@ int SMESH_ScalarBarActor::RenderOpaqueGeometry(vtkViewport *viewport)
         barHeight = (int)(coef1*size[1]);
         distrHeight = 0;
       }
-      
+
       barHeight = (int)(coef1*size[1]);
-      
+
       delta=(double)barWidth/numColors;
-      for (i=0; i<numPts/2; i++) {
+      for ( i = 0; i < numPts/2; i++ ) {
         x[0] = i*delta;
         x[1] = barHeight;
-        pts->SetPoint(2*i,x);                        
+        pts->SetPoint(2*i,x);
         x[1] = distrHeight + delimeter;
         pts->SetPoint(2*i+1,x);
       }
-      
-      if(GetDistributionVisibility() && distrVisibility) {
-        // Distribution points 
+
+      if ( GetDistributionVisibility() && distrVisibility ) {
+        // Distribution points
         shrink = delta*SHRINK_COEF;
         vtkIdType distPtsId=0;
         vtkIdType distPtsIds[4];
-        for(i=0; i<numColors; i++) {
+        for ( i = 0; i < numColors; i++ ) {
           if(myNbValues[i]) {
             itemH = distrHeight*((double)myNbValues[i]/maxValue);
-            
+
             // first point of polygon (quadrangle)
-            x[0] = i*delta+shrink; 
+            x[0] = i*delta+shrink;
             x[1] = 0;
             distPtsIds[0] = distPtsId;
             distrPts->SetPoint(distPtsId++,x);
-            
+
             // second point of polygon (quadrangle)
-            x[0] = i*delta+shrink; 
+            x[0] = i*delta+shrink;
             x[1] = itemH;
             distPtsIds[3] = distPtsId;
             distrPts->SetPoint(distPtsId++,x);
-            
+
             // third point of polygon (quadrangle)
-            x[0] = i*delta+delta-shrink; 
+            x[0] = i*delta+delta-shrink;
             x[1] = 0;
             distPtsIds[1] = distPtsId;
             distrPts->SetPoint(distPtsId++,x);
-            
+
             // fourth point of polygon (quadrangle)
-            x[0] = i*delta+delta-shrink; 
+            x[0] = i*delta+delta-shrink;
             x[1] = itemH;
             distPtsIds[2] = distPtsId;
             distrPts->SetPoint(distPtsId++,x);
-            
+
             // Add polygon into poly data
             distrPolys->InsertNextCell(4,distPtsIds);
           }
-        } 
+        }
       }
       // rnv end
     }
-    
+
     //polygons & cell colors
     unsigned char *rgba, *rgb;
     vtkIdType ptIds[4], dcCount=0;
-    for (i=0; i<numColors; i++)
-      {
+    for ( i = 0; i < numColors; i++ )
+    {
       ptIds[0] = 2*i;
       ptIds[1] = ptIds[0] + 1;
       ptIds[2] = ptIds[1] + 2;
@@ -560,22 +568,22 @@ int SMESH_ScalarBarActor::RenderOpaqueGeometry(vtkViewport *viewport)
       polys->InsertNextCell(4,ptIds);
 
       if ( isLogTable )
-        {
-        double rgbval = log10(range[0]) + 
+      {
+        double rgbval = log10(range[0]) +
           i*(log10(range[1])-log10(range[0]))/(numColors -1);
         rgba = lut->MapValue(pow(10.0,rgbval));
-        }
+      }
       else
-        {
+      {
         rgba = lut->MapValue(range[0] + (range[1] - range[0])*
                              ((double)i /(numColors-1.0)));
-        }
+      }
 
       rgb = colors->GetPointer(3*i); //write into array directly
       rgb[0] = rgba[0];
       rgb[1] = rgba[1];
       rgb[2] = rgba[2];
-      
+
       // rnv begin
       // Customization of the vtkScalarBarActor to show distribution histogram.
       if ( myDistributionColoringType == SMESH_MULTICOLOR_TYPE &&
@@ -594,62 +602,62 @@ int SMESH_ScalarBarActor::RenderOpaqueGeometry(vtkViewport *viewport)
     // Now position everything properly
     //
     double val;
-    if (this->Orientation == VTK_ORIENT_VERTICAL)
-      {
+    if ( this->Orientation == VTK_ORIENT_VERTICAL )
+    {
       int sizeTextData[2];
-      
+
       // center the title
       this->TitleActor->SetPosition(size[0]/2, 0.9*size[1]);
-      
-      for (i=0; i < this->NumberOfLabels; i++)
+
+      for ( i = 0; i < this->NumberOfLabels; i++ )
+      {
+        if ( this->NumberOfLabels > 1 )
         {
-        if (this->NumberOfLabels > 1)
-          {
           val = (double)i/(this->NumberOfLabels-1) *barHeight;
-          }
-        else 
-          {
+        }
+        else
+        {
           val = 0.5*barHeight;
-          }
+        }
         this->TextMappers[i]->GetSize(viewport,sizeTextData);
         this->TextMappers[i]->GetTextProperty()->SetJustificationToLeft();
         this->TextActors[i]->SetPosition(barWidth+3,
                                          val - sizeTextData[1]/2);
-        }
       }
+    }
     else
-      {
-      this->TitleActor->SetPosition(size[0]/2, 
+    {
+      this->TitleActor->SetPosition(size[0]/2,
                                     barHeight + labelSize[1] + 0.1*size[1]);
-      for (i=0; i < this->NumberOfLabels; i++)
-        {
+      for ( i = 0; i < this->NumberOfLabels; i++ )
+      {
         this->TextMappers[i]->GetTextProperty()->SetJustificationToCentered();
         if (this->NumberOfLabels > 1)
-          {
+        {
           val = (double)i/(this->NumberOfLabels-1) * barWidth;
-          }
+        }
         else
-          {
+        {
           val = 0.5*barWidth;
-          }
-        this->TextActors[i]->SetPosition(val, barHeight + 0.05*size[1]);
         }
+        this->TextActors[i]->SetPosition(val, barHeight + 0.05*size[1]);
       }
+    }
 
     this->BuildTime.Modified();
-    }
+  }
 
   // Everything is built, just have to render
-  if (this->Title != NULL)
-    {
+  if ( this->Title != NULL )
+  {
     renderedSomething += this->TitleActor->RenderOpaqueGeometry(viewport);
-    }
+  }
   this->ScalarBarActor->RenderOpaqueGeometry(viewport);
   this->myDistributionActor->RenderOpaqueGeometry(viewport);
-  for (i=0; i<this->NumberOfLabels; i++)
-    {
+  for ( i = 0; i < this->NumberOfLabels; i++ )
+  {
     renderedSomething += this->TextActors[i]->RenderOpaqueGeometry(viewport);
-    }
+  }
 
   renderedSomething = (renderedSomething > 0)?(1):(0);
 
@@ -662,50 +670,50 @@ void SMESH_ScalarBarActor::PrintSelf(ostream& os, vtkIndent indent)
   this->Superclass::PrintSelf(os,indent);
 
   if ( this->LookupTable )
-    {
+  {
     os << indent << "Lookup Table:\n";
     this->LookupTable->PrintSelf(os,indent.GetNextIndent());
-    }
+  }
   else
-    {
+  {
     os << indent << "Lookup Table: (none)\n";
-    }
+  }
 
   if (this->TitleTextProperty)
-    {
+  {
     os << indent << "Title Text Property:\n";
     this->TitleTextProperty->PrintSelf(os,indent.GetNextIndent());
-    }
+  }
   else
-    {
+  {
     os << indent << "Title Text Property: (none)\n";
-    }
+  }
 
   if (this->LabelTextProperty)
-    {
+  {
     os << indent << "Label Text Property:\n";
     this->LabelTextProperty->PrintSelf(os,indent.GetNextIndent());
-    }
+  }
   else
-    {
+  {
     os << indent << "Label Text Property: (none)\n";
-    }
+  }
 
   os << indent << "Title: " << (this->Title ? this->Title : "(none)") << "\n";
-  os << indent << "Maximum Number Of Colors: " 
+  os << indent << "Maximum Number Of Colors: "
      << this->MaximumNumberOfColors << "\n";
   os << indent << "Number Of Labels: " << this->NumberOfLabels << "\n";
   os << indent << "Number Of Labels Built: " << this->NumberOfLabelsBuilt << "\n";
 
   os << indent << "Orientation: ";
   if ( this->Orientation == VTK_ORIENT_HORIZONTAL )
-    {
+  {
     os << "Horizontal\n";
-    }
+  }
   else
-    {
+  {
     os << "Vertical\n";
-    }
+  }
 
   os << indent << "Label Format: " << this->LabelFormat << "\n";
 }
@@ -715,7 +723,7 @@ void SMESH_ScalarBarActor::ShallowCopy(vtkProp *prop)
 {
   SMESH_ScalarBarActor *a = SMESH_ScalarBarActor::SafeDownCast(prop);
   if ( a != NULL )
-    {
+  {
     this->SetPosition2(a->GetPosition2());
     this->SetLookupTable(a->GetLookupTable());
     this->SetMaximumNumberOfColors(a->GetMaximumNumberOfColors());
@@ -724,25 +732,25 @@ void SMESH_ScalarBarActor::ShallowCopy(vtkProp *prop)
     this->SetTitleTextProperty(a->GetTitleTextProperty());
     this->SetLabelFormat(a->GetLabelFormat());
     this->SetTitle(a->GetTitle());
-    this->GetPositionCoordinate()->SetCoordinateSystem(
-      a->GetPositionCoordinate()->GetCoordinateSystem());    
-    this->GetPositionCoordinate()->SetValue(
-      a->GetPositionCoordinate()->GetValue());
-    this->GetPosition2Coordinate()->SetCoordinateSystem(
-      a->GetPosition2Coordinate()->GetCoordinateSystem());    
-    this->GetPosition2Coordinate()->SetValue(
-      a->GetPosition2Coordinate()->GetValue());
-    }
+    this->GetPositionCoordinate()->SetCoordinateSystem
+      (a->GetPositionCoordinate()->GetCoordinateSystem());
+    this->GetPositionCoordinate()->SetValue
+      (a->GetPositionCoordinate()->GetValue());
+    this->GetPosition2Coordinate()->SetCoordinateSystem
+      (a->GetPosition2Coordinate()->GetCoordinateSystem());
+    this->GetPosition2Coordinate()->SetValue
+      (a->GetPosition2Coordinate()->GetValue());
+  }
 
   // Now do superclass
   this->vtkActor2D::ShallowCopy(prop);
 }
 
 //----------------------------------------------------------------------------
-void SMESH_ScalarBarActor::AllocateAndSizeLabels(int *labelSize, 
-                                              int *size,
-                                              vtkViewport *viewport,
-                                              double *range)
+void SMESH_ScalarBarActor::AllocateAndSizeLabels(int         *labelSize,
+                                                 int         *size,
+                                                 vtkViewport *viewport,
+                                                 double      *range)
 {
   labelSize[0] = labelSize[1] = 0;
 
@@ -753,55 +761,55 @@ void SMESH_ScalarBarActor::AllocateAndSizeLabels(int *labelSize,
 
   double val;
   int i;
-  
+
   // TODO: this should be optimized, maybe by keeping a list of
   // allocated mappers, in order to avoid creation/destruction of
   // their underlying text properties (i.e. each time a mapper is
   // created, text properties are created and shallow-assigned a font size
   // which value might be "far" from the target font size).
 
-  // is this a vtkLookupTable or a subclass of vtkLookupTable 
+  // is this a vtkLookupTable or a subclass of vtkLookupTable
   // with its scale set to log
   vtkLookupTable *LUT = vtkLookupTable::SafeDownCast( this->LookupTable );
   int isLogTable = 0;
   if ( LUT )
-    {
+  {
     if ( LUT->GetScale() == VTK_SCALE_LOG10 )
-      {
-      isLogTable = 1; 
-      }
+    {
+      isLogTable = 1;
     }
+  }
 
-  for (i=0; i < this->NumberOfLabels; i++)
-    {
+  for ( i = 0; i < this->NumberOfLabels; i++ )
+  {
     this->TextMappers[i] = vtkTextMapper::New();
 
     if ( isLogTable )
-      {
+    {
       double lval;
-      if (this->NumberOfLabels > 1)
-        {
+      if ( this->NumberOfLabels > 1 )
+      {
         lval = log10(range[0]) + (double)i/(this->NumberOfLabels-1) *
           (log10(range[1])-log10(range[0]));
-        }
+      }
       else
-        {
+      {
         lval = log10(range[0]) + 0.5*(log10(range[1])-log10(range[0]));
-        }
-      val = pow(10.0,lval);
       }
+      val = pow(10.0,lval);
+    }
     else
+    {
+      if ( this->NumberOfLabels > 1 )
       {
-      if (this->NumberOfLabels > 1)
-        {
-        val = range[0] + 
+        val = range[0] +
           (double)i/(this->NumberOfLabels-1) * (range[1]-range[0]);
-        }
+      }
       else
-        {
+      {
         val = range[0] + 0.5*(range[1]-range[0]);
-        }
       }
+    }
 
     sprintf(string, this->LabelFormat, val);
     this->TextMappers[i]->SetInput(string);
@@ -812,64 +820,63 @@ void SMESH_ScalarBarActor::AllocateAndSizeLabels(int *labelSize,
     // which will be modified later). This allows text actors to
     // share the same text property, and in that case specifically allows
     // the title and label text prop to be the same.
-    this->TextMappers[i]->GetTextProperty()->ShallowCopy(
-      this->LabelTextProperty);
+    this->TextMappers[i]->GetTextProperty()->ShallowCopy(this->LabelTextProperty);
 
     this->TextActors[i] = vtkActor2D::New();
     this->TextActors[i]->SetMapper(this->TextMappers[i]);
     this->TextActors[i]->SetProperty(this->GetProperty());
     this->TextActors[i]->GetPositionCoordinate()->
       SetReferenceCoordinate(this->PositionCoordinate);
-    }
+  }
 
-  if (this->NumberOfLabels)
-    {
+  if ( this->NumberOfLabels )
+  {
     int targetWidth, targetHeight;
     // rnv begin
     // Customization of the vtkScalarBarActor to show distribution histogram.
     bool distrVisibility = ( this->MaximumNumberOfColors == (int) this->myNbValues.size() );
     double coef;
-    if( GetDistributionVisibility() && distrVisibility )
-      if(this->Orientation == VTK_ORIENT_VERTICAL)
+    if ( GetDistributionVisibility() && distrVisibility )
+      if ( this->Orientation == VTK_ORIENT_VERTICAL )
         coef = 0.4;
-      else 
+      else
         coef = 0.18;
-    else 
-      if(this->Orientation == VTK_ORIENT_VERTICAL)
+    else
+      if (this->Orientation == VTK_ORIENT_VERTICAL )
         coef = 0.6;
-      else 
+      else
         coef=0.25;
 
 
     if ( this->Orientation == VTK_ORIENT_VERTICAL )
-      {
+    {
       targetWidth = (int)(coef*size[0]);
       targetHeight = (int)(0.86*size[1]/this->NumberOfLabels);
-      }
+    }
     else
-      {
+    {
       targetWidth = (int)(size[0]*0.8/this->NumberOfLabels);
       targetHeight = (int)(coef*size[1]);
-      }
-    // rnv end
-    
-    vtkTextMapper::SetMultipleConstrainedFontSize(viewport, 
-                                                  targetWidth, 
-                                                  targetHeight,
-                                                  this->TextMappers,
-                                                  this->NumberOfLabels,
-                                                  labelSize);
     }
+    // rnv end
+
+    vtkTextMapper::SetMultipleConstrainedFontSize( viewport,
+                                                   targetWidth,
+                                                   targetHeight,
+                                                   this->TextMappers,
+                                                   this->NumberOfLabels,
+                                                   labelSize );
+  }
 }
 
 //----------------------------------------------------------------------------
-void SMESH_ScalarBarActor::SizeTitle(int *titleSize,
-                                     int *size,
+void SMESH_ScalarBarActor::SizeTitle(int         *titleSize,
+                                     int         *size,
                                      vtkViewport *viewport)
 {
   titleSize[0] = titleSize[1] = 0;
 
-  if (this->Title == NULL || !strlen(this->Title))
+  if ( this->Title == NULL || !strlen(this->Title) )
   {
     return;
   }
@@ -902,36 +909,43 @@ void SMESH_ScalarBarActor::SizeTitle(int *titleSize,
 
 
 /*--------------------------------------------------------------------------*/
-void SMESH_ScalarBarActor::SetDistributionVisibility(int flag) {
-  myDistributionActor->SetVisibility(flag);
+void SMESH_ScalarBarActor::SetDistributionVisibility( int flag )
+{
+  myDistributionActor->SetVisibility( flag );
   Modified();
 }
 
 
 /*--------------------------------------------------------------------------*/
-int SMESH_ScalarBarActor::GetDistributionVisibility() {
+int SMESH_ScalarBarActor::GetDistributionVisibility()
+{
   return myDistributionActor->GetVisibility();
 }
 
 
-void SMESH_ScalarBarActor::SetDistribution(std::vector<int> theNbValues) {
+void SMESH_ScalarBarActor::SetDistribution( const std::vector<int>& theNbValues )
+{
   myNbValues = theNbValues;
-} 
+}
 
 
-void SMESH_ScalarBarActor::SetDistributionColor (double rgb[3]) {
+void SMESH_ScalarBarActor::SetDistributionColor( double rgb[3] )
+{
   myDistributionActor->GetProperty()->SetColor(rgb);
   Modified();
 }
 
-void SMESH_ScalarBarActor::GetDistributionColor (double rgb[3]) {
+void SMESH_ScalarBarActor::GetDistributionColor( double rgb[3] )
+{
   myDistributionActor->GetProperty()->GetColor(rgb);
 }
 
-void SMESH_ScalarBarActor::SetTitleOnlyVisibility( bool theTitleOnlyVisibility) {
+void SMESH_ScalarBarActor::SetTitleOnlyVisibility( bool theTitleOnlyVisibility )
+{
   myTitleOnlyVisibility = theTitleOnlyVisibility;
 }
 
-bool SMESH_ScalarBarActor::GetTitleOnlyVisibility() {
+bool SMESH_ScalarBarActor::GetTitleOnlyVisibility()
+{
   return myTitleOnlyVisibility;
 }
index ffc91bb118b54aef89cd046e5d3c5991ad9ef377..c5e721b2374fe5cb47bc942fcb2a44eae628f2a0 100644 (file)
@@ -174,7 +174,7 @@ class SMESHOBJECT_EXPORT SMESH_ScalarBarActor: public vtkActor2D {
   virtual int GetDistributionVisibility();
   // Description:
   // Set distribution
-  virtual void SetDistribution(std::vector<int> theNbValues);
+  virtual void SetDistribution(const std::vector<int>& theNbValues);
   
   // Description: 
   // Set distribution coloring type (SMESH_MONOCOLOR_TYPE or SMESH_MULTICOLOR_TYPE)
index 5e5f0d289d275eff3d2c3d10a6b99d80b88d400d..ef514b353b0388fdcf4b61eb0cb8924a1742327e 100644 (file)
 #define _OBJECTPOOL_HXX_
 
 #include <vector>
-//#include <stack>
 #include <iostream>
 
+#include "SMDS_Iterator.hxx"
+
 namespace
 {
   // assure deallocation of memory of a vector
@@ -33,18 +34,22 @@ namespace
   }
 }
 
+template<class X> class ObjectPoolIterator;
+
 template<class X> class ObjectPool
 {
 
 private:
-  std::vector<X*> _chunkList;
+  std::vector<X*>   _chunkList;
   std::vector<bool> _freeList;
-  int _nextFree;
-  int _maxAvail;
-  int _chunkSize;
-  int _maxOccupied;
-  int _nbHoles;
-  int _lastDelChunk;
+  int               _nextFree;    // either the 1st hole or last added
+  int               _maxAvail;    // nb allocated elements
+  int               _chunkSize;
+  int               _maxOccupied; // max used ID
+  int               _nbHoles;
+  int               _lastDelChunk;
+
+  friend class ObjectPoolIterator<X>;
 
   int getNextFree()
   {
@@ -76,16 +81,16 @@ private:
   }
 
 public:
-  ObjectPool(int nblk)
+  ObjectPool(int nblk = 1024)
   {
-    _chunkSize = nblk;
-    _nextFree = 0;
-    _maxAvail = 0;
-    _maxOccupied = 0;
-    _nbHoles = 0;
+    _chunkSize    = nblk;
+    _nextFree     = 0;
+    _maxAvail     = 0;
+    _maxOccupied  = -1;
+    _nbHoles      = 0;
+    _lastDelChunk = 0;
     _chunkList.clear();
     _freeList.clear();
-    _lastDelChunk = 0;
   }
 
   virtual ~ObjectPool()
@@ -105,16 +110,16 @@ public:
         _freeList.insert(_freeList.end(), _chunkSize, true);
         _maxAvail += _chunkSize;
         _freeList[_nextFree] = false;
-        obj = newChunk; // &newChunk[0];
+        obj = newChunk;
       }
     else
       {
         int chunkId = _nextFree / _chunkSize;
         int rank = _nextFree - chunkId * _chunkSize;
         _freeList[_nextFree] = false;
-        obj = _chunkList[chunkId] + rank; // &_chunkList[chunkId][rank];
+        obj = _chunkList[chunkId] + rank;
       }
-    if (_nextFree < _maxOccupied)
+    if (_nextFree <= _maxOccupied)
       {
         _nbHoles-=1;
       }
@@ -122,7 +127,6 @@ public:
       {
         _maxOccupied = _nextFree;
       }
-    //obj->init();
     return obj;
   }
 
@@ -148,10 +152,10 @@ public:
     if (toFree < _nextFree)
       _nextFree = toFree;
     if (toFree < _maxOccupied)
-      _nbHoles += 1;
+      ++_nbHoles;
+    else
+      --_maxOccupied;
     _lastDelChunk = i;
-    //obj->clean();
-    //checkDelete(i); compactage non fait
   }
 
   void clear()
@@ -167,6 +171,37 @@ public:
     clearVector( _freeList );
   }
 
+  // nb allocated elements
+  size_t size() const
+  {
+    return _freeList.size();
+  }
+
+  // nb used elements
+  size_t nbElements() const
+  {
+    return _maxOccupied + 1 - _nbHoles;
+  }
+
+  // return an element w/o any check
+  const X* operator[]( size_t i ) const // i < size()
+  {
+    int chunkId = i / _chunkSize;
+    int    rank = i - chunkId * _chunkSize;
+    return _chunkList[ chunkId ] + rank;
+  }
+
+  // return only being used element
+  const X* at( size_t i ) const // i < size()
+  {
+    if ( i >= size() || _freeList[ i ] )
+      return 0;
+
+    int chunkId = i / _chunkSize;
+    int    rank = i - chunkId * _chunkSize;
+    return _chunkList[ chunkId ] + rank;
+  }
+
   //  void destroy(int toFree)
   //  {
   //    // no control 0<= toFree < _freeList.size()
@@ -177,4 +212,41 @@ public:
 
 };
 
+template<class X> class ObjectPoolIterator : public SMDS_Iterator<const X*>
+{
+  const ObjectPool<X>& _pool;
+  int                  _i, _nbFound;
+public:
+
+  ObjectPoolIterator( const ObjectPool<X>& pool ) : _pool( pool ), _i( 0 ), _nbFound( 0 )
+  {
+    if ( more() && _pool._freeList[ _i ] == true )
+    {
+      next();
+      --_nbFound;
+    }
+  }
+
+  virtual bool more()
+  {
+    return ( _i <= _pool._maxOccupied && _nbFound < (int)_pool.nbElements() );
+  }
+
+  virtual const X* next()
+  {
+    const X* x = 0;
+    if ( more() )
+    {
+      x = _pool[ _i ];
+
+      ++_nbFound;
+
+      for ( ++_i; _i <= _pool._maxOccupied; ++_i )
+        if ( _pool._freeList[ _i ] == false )
+          break;
+    }
+    return x;
+  }
+};
+
 #endif
index 10ee0d5e03fd7f54a7c94cd731cdabfbb3c66ce9..491f4f0681a51b1efe00af773b0bb3bbaf9aaa96 100644 (file)
@@ -98,6 +98,7 @@ enum SMDSAbs_EntityType {
   SMDSEntity_TriQuad_Hexa,
   SMDSEntity_Penta,
   SMDSEntity_Quad_Penta,
+  SMDSEntity_BiQuad_Penta,
   SMDSEntity_Hexagonal_Prism,
   SMDSEntity_Polyhedra,
   SMDSEntity_Quad_Polyhedra,
index ef666df7a2265e35b4446d72b1da1cf4e78d4e8a..c4ead4dac025f38aa829ce2f1619d621c3e8d2f7 100644 (file)
@@ -61,6 +61,7 @@ int SMDS_Downward::getCellDimension(unsigned char cellType)
       _cellDimension[VTK_TRIQUADRATIC_HEXAHEDRON] = 3;
       _cellDimension[VTK_WEDGE] = 3;
       _cellDimension[VTK_QUADRATIC_WEDGE] = 3;
+      _cellDimension[VTK_BIQUADRATIC_QUADRATIC_WEDGE] = 3;
       _cellDimension[VTK_PYRAMID] = 3;
       _cellDimension[VTK_QUADRATIC_PYRAMID] = 3;
       _cellDimension[VTK_HEXAGONAL_PRISM] = 3;
index 5d8294700d96607f3d3cd38eb93ad8405dd1e60a..40caa2c8854d51f04cbb99b91ba3f5943a34f8cd 100644 (file)
@@ -1556,9 +1556,15 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolumeFromVtkIdsWithID(const std::vector<vtkIdTyp
     case VTK_QUADRATIC_WEDGE:
       myInfo.myNbQuadPrisms++;
       break;
+    case VTK_BIQUADRATIC_QUADRATIC_WEDGE:
+      myInfo.myNbBiQuadPrisms++;
+      break;
     case VTK_QUADRATIC_HEXAHEDRON:
       myInfo.myNbQuadHexas++;
       break;
+    case VTK_TRIQUADRATIC_HEXAHEDRON:
+      myInfo.myNbTriQuadHexas++;
+      break;
 //#ifdef VTK_HAVE_POLYHEDRON
     case VTK_POLYHEDRON:
       myInfo.myNbPolyhedrons++;
@@ -1690,10 +1696,10 @@ const SMDS_MeshNode * SMDS_Mesh::FindNodeVtk(int vtkId) const
   return (const SMDS_MeshNode *)myNodes[vtkId+1];
 }
 
-///////////////////////////////////////////////////////////////////////////////
-///Create a triangle and add it to the current mesh. This method do not bind an
-///ID to the create triangle.
-///////////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////
+///Create a triangle and add it to the current mesh. This method does not bind
+///an ID to the create triangle.
+//////////////////////////////////////////////////////////////////////////////
 SMDS_MeshFace * SMDS_Mesh::createTriangle(const SMDS_MeshNode * node1,
                                           const SMDS_MeshNode * node2,
                                           const SMDS_MeshNode * node3,
@@ -1740,10 +1746,10 @@ SMDS_MeshFace * SMDS_Mesh::createTriangle(const SMDS_MeshNode * node1,
   }
 }
 
-///////////////////////////////////////////////////////////////////////////////
-///Create a quadrangle and add it to the current mesh. This methode do not bind
-///a ID to the create triangle.
-///////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////
+///Create a quadrangle and add it to the current mesh. This method does not bind
+///an ID to the create triangle.
+////////////////////////////////////////////////////////////////////////////////
 SMDS_MeshFace * SMDS_Mesh::createQuadrangle(const SMDS_MeshNode * node1,
                                             const SMDS_MeshNode * node2,
                                             const SMDS_MeshNode * node3,
@@ -2458,6 +2464,49 @@ const SMDS_MeshElement* SMDS_Mesh::FindElement (const vector<const SMDS_MeshNode
   return NULL;
 }
 
+//================================================================================
+/*!
+ * \brief Return elements including all given nodes
+ *  \param [in] nodes - nodes to find elements around
+ *  \param [out] foundElems - the found elements
+ *  \param [in] type - type of elements to find
+ *  \return int - a number of found elements
+ */
+//================================================================================
+
+int SMDS_Mesh::GetElementsByNodes(const std::vector<const SMDS_MeshNode *>& nodes,
+                                  std::vector<const SMDS_MeshElement *>&    foundElems,
+                                  const SMDSAbs_ElementType                 type)
+{
+  // chose a node with minimal number of inverse elements
+  const SMDS_MeshNode* n0 = nodes[0];
+  int minNbInverse = n0 ? n0->NbInverseElements( type ) : 1000;
+  for ( size_t i = 1; i < nodes.size(); ++i )
+    if ( nodes[i] && nodes[i]->NbInverseElements( type ) < minNbInverse )
+    {
+      n0 = nodes[i];
+      minNbInverse = n0->NbInverseElements( type );
+    }
+
+  foundElems.clear();
+  if ( n0 )
+  {
+    foundElems.reserve( minNbInverse );
+    SMDS_ElemIteratorPtr eIt = n0->GetInverseElementIterator( type );
+    while ( eIt->more() )
+    {
+      const SMDS_MeshElement* e = eIt->next();
+      bool includeAll = true;
+      for ( size_t i = 0; i < nodes.size() &&  includeAll; ++i )
+        if ( nodes[i] != n0 && e->GetNodeIndex( nodes[i] ) < 0 )
+          includeAll = false;
+      if ( includeAll )
+        foundElems.push_back( e );
+    }
+  }
+  return foundElems.size();
+}
+
 //=======================================================================
 //function : DumpNodes
 //purpose  :
@@ -4167,7 +4216,7 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
 
 //=======================================================================
 //function : AddVolume
-//purpose  :
+//purpose  : 2d order Pentahedron (prism) with 15 nodes
 //=======================================================================
 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
                                       const SMDS_MeshNode * n2,
@@ -4195,7 +4244,7 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
 
 //=======================================================================
 //function : AddVolumeWithID
-//purpose  :
+//purpose  : 2d order Pentahedron (prism) with 15 nodes
 //=======================================================================
 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(int n1, int n2, int n3,
                                             int n4, int n5, int n6,
@@ -4224,7 +4273,7 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(int n1, int n2, int n3,
 
 //=======================================================================
 //function : AddVolumeWithID
-//purpose  : 2d order Pentahedron with 15 nodes
+//purpose  : 2d order Pentahedron (prism) with 15 nodes
 //=======================================================================
 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
                                             const SMDS_MeshNode * n2,
@@ -4291,6 +4340,149 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
   return volvtk;
 }
 
+//=======================================================================
+//function : AddVolume
+//purpose  : 2d order Pentahedron (prism) with 18 nodes
+//=======================================================================
+SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
+                                      const SMDS_MeshNode * n2,
+                                      const SMDS_MeshNode * n3,
+                                      const SMDS_MeshNode * n4,
+                                      const SMDS_MeshNode * n5,
+                                      const SMDS_MeshNode * n6,
+                                      const SMDS_MeshNode * n12,
+                                      const SMDS_MeshNode * n23,
+                                      const SMDS_MeshNode * n31,
+                                      const SMDS_MeshNode * n45,
+                                      const SMDS_MeshNode * n56,
+                                      const SMDS_MeshNode * n64,
+                                      const SMDS_MeshNode * n14,
+                                      const SMDS_MeshNode * n25,
+                                      const SMDS_MeshNode * n36,
+                                      const SMDS_MeshNode * n1245,
+                                      const SMDS_MeshNode * n2356,
+                                      const SMDS_MeshNode * n1346)
+{
+  //MESSAGE("AddVolume penta18");
+  int ID = myElementIDFactory->GetFreeID();
+  SMDS_MeshVolume * v =
+    SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n6, n12, n23, n31,
+                               n45, n56, n64, n14, n25, n36, n1245, n2356, n1346, ID);
+  if(v==NULL) myElementIDFactory->ReleaseID(ID);
+  return v;
+}
+
+//=======================================================================
+//function : AddVolumeWithID
+//purpose  : 2d order Pentahedron (prism) with 18 nodes
+//=======================================================================
+SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(int n1, int n2, int n3,
+                                            int n4, int n5, int n6,
+                                            int n12,int n23,int n31,
+                                            int n45,int n56,int n64,
+                                            int n14,int n25,int n36,
+                                            int n1245, int n2356, int n1346, int ID)
+{
+  //MESSAGE("AddVolumeWithID penta18 " << ID);
+  return SMDS_Mesh::AddVolumeWithID
+    ((SMDS_MeshNode*) myNodeIDFactory->MeshElement(n1) ,
+     (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n2) ,
+     (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n3) ,
+     (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n4) ,
+     (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n5) ,
+     (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n6) ,
+     (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n12),
+     (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n23),
+     (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n31),
+     (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n45),
+     (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n56),
+     (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n64),
+     (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n14),
+     (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n25),
+     (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n36),
+     (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n1245),
+     (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n2356),
+     (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n1346),
+     ID);
+}
+
+//=======================================================================
+//function : AddVolumeWithID
+//purpose  : 2d order Pentahedron (prism) with 18 nodes
+//=======================================================================
+SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
+                                            const SMDS_MeshNode * n2,
+                                            const SMDS_MeshNode * n3,
+                                            const SMDS_MeshNode * n4,
+                                            const SMDS_MeshNode * n5,
+                                            const SMDS_MeshNode * n6,
+                                            const SMDS_MeshNode * n12,
+                                            const SMDS_MeshNode * n23,
+                                            const SMDS_MeshNode * n31,
+                                            const SMDS_MeshNode * n45,
+                                            const SMDS_MeshNode * n56,
+                                            const SMDS_MeshNode * n64,
+                                            const SMDS_MeshNode * n14,
+                                            const SMDS_MeshNode * n25,
+                                            const SMDS_MeshNode * n36,
+                                            const SMDS_MeshNode * n1245,
+                                            const SMDS_MeshNode * n2356,
+                                            const SMDS_MeshNode * n1346,
+                                            int ID)
+{
+  //MESSAGE("AddVolumeWithID penta18 "<< ID);
+  if (!n1 || !n2 || !n3 || !n4 || !n5 || !n6 || !n12 || !n23 ||
+      !n31 || !n45 || !n56 || !n64 || !n14 || !n25 || !n36 || !n1245 || !n2356 || !n1346)
+    return 0;
+  if(hasConstructionFaces()) {
+    // creation quadratic faces - not implemented
+    return 0;
+  }
+  // --- retrieve nodes ID
+  myNodeIds.resize(18);
+  myNodeIds[0] = n1->getVtkId();
+  myNodeIds[1] = n2->getVtkId();
+  myNodeIds[2] = n3->getVtkId();
+
+  myNodeIds[3] = n4->getVtkId();
+  myNodeIds[4] = n5->getVtkId();
+  myNodeIds[5] = n6->getVtkId();
+
+  myNodeIds[6] = n12->getVtkId();
+  myNodeIds[7] = n23->getVtkId();
+  myNodeIds[8] = n31->getVtkId();
+
+  myNodeIds[9] = n45->getVtkId();
+  myNodeIds[10] = n56->getVtkId();
+  myNodeIds[11] = n64->getVtkId();
+
+  myNodeIds[12] = n14->getVtkId();
+  myNodeIds[13] = n25->getVtkId();
+  myNodeIds[14] = n36->getVtkId();
+
+  myNodeIds[15] = n1245->getVtkId();
+  myNodeIds[16] = n2356->getVtkId();
+  myNodeIds[17] = n1346->getVtkId();
+
+  SMDS_VtkVolume *volvtk = myVolumePool->getNew();
+  volvtk->init(myNodeIds, this);
+  if (!this->registerElement(ID,volvtk))
+  {
+    this->myGrid->GetCellTypesArray()->SetValue(volvtk->getVtkId(), VTK_EMPTY_CELL);
+    myVolumePool->destroy(volvtk);
+    return 0;
+  }
+  adjustmyCellsCapacity(ID);
+  myCells[ID] = volvtk;
+  myInfo.myNbBiQuadPrisms++;
+
+  //  if (!registerElement(ID, volvtk)) {
+  //    RemoveElement(volvtk, false);
+  //    volvtk = NULL;
+  //  }
+  return volvtk;
+}
+
 
 //=======================================================================
 //function : AddVolume
index b1af99a1d1e6c2d0e8f5b8347130ccd2f4328f93..c1fea287ffcff1cea6a770b371b22655cf76dd3e 100644 (file)
@@ -454,6 +454,53 @@ public:
                                      const SMDS_MeshNode * n25,
                                      const SMDS_MeshNode * n36);
 
+  // 2d order Pentahedron with 18 nodes
+  virtual SMDS_MeshVolume* AddVolumeWithID(int n1, int n2, int n3,
+                                           int n4, int n5, int n6,
+                                           int n12,int n23,int n31,
+                                           int n45,int n56,int n64,
+                                           int n14,int n25,int n36,
+                                           int n1245, int n2356, int n1346,
+                                           int ID);
+  virtual SMDS_MeshVolume* AddVolumeWithID(const SMDS_MeshNode * n1,
+                                           const SMDS_MeshNode * n2,
+                                           const SMDS_MeshNode * n3,
+                                           const SMDS_MeshNode * n4,
+                                           const SMDS_MeshNode * n5,
+                                           const SMDS_MeshNode * n6,
+                                           const SMDS_MeshNode * n12,
+                                           const SMDS_MeshNode * n23,
+                                           const SMDS_MeshNode * n31,
+                                           const SMDS_MeshNode * n45,
+                                           const SMDS_MeshNode * n56,
+                                           const SMDS_MeshNode * n64,
+                                           const SMDS_MeshNode * n14,
+                                           const SMDS_MeshNode * n25,
+                                           const SMDS_MeshNode * n36,
+                                           const SMDS_MeshNode * n1245,
+                                           const SMDS_MeshNode * n2356,
+                                           const SMDS_MeshNode * n1346,
+                                           int ID);
+  virtual SMDS_MeshVolume* AddVolume(const SMDS_MeshNode * n1,
+                                     const SMDS_MeshNode * n2,
+                                     const SMDS_MeshNode * n3,
+                                     const SMDS_MeshNode * n4,
+                                     const SMDS_MeshNode * n5,
+                                     const SMDS_MeshNode * n6,
+                                     const SMDS_MeshNode * n12,
+                                     const SMDS_MeshNode * n23,
+                                     const SMDS_MeshNode * n31,
+                                     const SMDS_MeshNode * n45,
+                                     const SMDS_MeshNode * n56,
+                                     const SMDS_MeshNode * n64,
+                                     const SMDS_MeshNode * n14,
+                                     const SMDS_MeshNode * n25,
+                                     const SMDS_MeshNode * n36,
+                                     const SMDS_MeshNode * n1245,
+                                     const SMDS_MeshNode * n2356,
+                                     const SMDS_MeshNode * n1346);
+
+
   // 2d oreder Hexahedrons with 20 nodes
   virtual SMDS_MeshVolume* AddVolumeWithID(int n1, int n2, int n3, int n4,
                                            int n5, int n6, int n7, int n8,
@@ -689,6 +736,9 @@ public:
   static const SMDS_MeshElement* FindElement(const std::vector<const SMDS_MeshNode *>& nodes,
                                              const SMDSAbs_ElementType                 type=SMDSAbs_All,
                                              const bool                                noMedium=true);
+  static int GetElementsByNodes(const std::vector<const SMDS_MeshNode *>& nodes,
+                                std::vector<const SMDS_MeshElement *>&    foundElems,
+                                const SMDSAbs_ElementType                 type=SMDSAbs_All);
 
   /*!
    * \brief Raise an exception if free memory (ram+swap) too low
index 6b7f04e0855004e88b399e0fe9349bfc0b4ee261..7175ae5d457c3cd80695fcea22172c7f9845942e 100644 (file)
@@ -66,6 +66,7 @@ VTKCellType SMDS_MeshCell::toVtkType (SMDSAbs_EntityType smdsType)
     vtkTypes[ SMDSEntity_TriQuad_Hexa ]      = VTK_TRIQUADRATIC_HEXAHEDRON;
     vtkTypes[ SMDSEntity_Penta ]             = VTK_WEDGE;
     vtkTypes[ SMDSEntity_Quad_Penta ]        = VTK_QUADRATIC_WEDGE;
+    vtkTypes[ SMDSEntity_BiQuad_Penta ]      = VTK_BIQUADRATIC_QUADRATIC_WEDGE;
     vtkTypes[ SMDSEntity_Hexagonal_Prism ]   = VTK_HEXAGONAL_PRISM;
     vtkTypes[ SMDSEntity_Polyhedra ]         = VTK_POLYHEDRON;
     //vtkTypes[ SMDSEntity_Quad_Polyhedra ]    = ;
@@ -153,9 +154,13 @@ const std::vector< int >& SMDS_MeshCell::toVtkOrder(SMDSAbs_EntityType smdsType)
       toVtkInterlaces[SMDSEntity_Penta].assign( &ids[0], &ids[0]+6 );
     }
     {
-      const int ids[] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14};
+      const int ids[] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14}; // TODO: check
       toVtkInterlaces[SMDSEntity_Quad_Penta].assign( &ids[0], &ids[0]+15 );
     }
+    {
+      const int ids[] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17};// TODO: check
+      toVtkInterlaces[SMDSEntity_BiQuad_Penta].assign( &ids[0], &ids[0]+18 );
+    }
     {
       const int ids[] = {0,5,4,3,2,1,6,11,10,9,8,7};
       toVtkInterlaces[SMDSEntity_Hexagonal_Prism].assign( &ids[0], &ids[0]+12 );
@@ -254,6 +259,10 @@ const std::vector<int>& SMDS_MeshCell::reverseSmdsOrder(SMDSAbs_EntityType smdsT
       reverseInterlaces[SMDSEntity_Quad_Penta].assign( &ids[0], &ids[0]+15 );
     }
     {
+      const int ids[] = {0,2,1,3,5,4, 8,7,6,11,10,9,12,14,13,15,16,17};
+      reverseInterlaces[SMDSEntity_BiQuad_Penta].assign( &ids[0], &ids[0]+18 );
+    }
+   {
       const int ids[] = {0,5,4,3,2,1,6,11,10,9,8,7};
       reverseInterlaces[SMDSEntity_Hexagonal_Prism].assign( &ids[0], &ids[0]+12 );
     }
@@ -414,6 +423,7 @@ SMDSAbs_ElementType SMDS_MeshCell::toSmdsType(SMDSAbs_EntityType entityType)
   case SMDSEntity_TriQuad_Hexa:
   case SMDSEntity_Penta:
   case SMDSEntity_Quad_Penta:
+  case SMDSEntity_BiQuad_Penta:
   case SMDSEntity_Hexagonal_Prism:
   case SMDSEntity_Polyhedra:
   case SMDSEntity_Quad_Polyhedra: return SMDSAbs_Volume;
index eb2331f989e42b7c6b311800cd53700300658e23..f61079353f7a78bbd240f86eae85c1e02d572f1a 100644 (file)
@@ -163,7 +163,7 @@ bool SMDS_MeshGroup::Remove(const SMDS_MeshElement * theElem)
 
 bool SMDS_MeshGroup::Contains(const SMDS_MeshElement * theElem) const
 {
-        return myElements.find(theElem)!=myElements.end();
+  return myElements.find(theElem) != myElements.end();
 }
 
 //=======================================================================
index d8bcf90d51f8c2f90e7cd9762c049fd6b7861555..250442335d971018fa26b457b03c10410504d036 100644 (file)
@@ -29,6 +29,7 @@
 #include "SMESH_SMDS.hxx"
 
 #include "SMDS_MeshElement.hxx"
+#include<utilities.h>
 
 class SMDS_EXPORT SMDS_MeshInfo
 {
@@ -64,6 +65,8 @@ public:
   inline int NbPrisms  (SMDSAbs_ElementOrder order = ORDER_ANY) const;
   inline int NbHexPrisms(SMDSAbs_ElementOrder order = ORDER_ANY) const;
   int NbTriQuadHexas() const { return myNbTriQuadHexas; }
+  int NbQuadPrisms() const { return myNbQuadPrisms; }
+  int NbBiQuadPrisms() const { return myNbBiQuadPrisms; }
   int NbPolyhedrons() const { return myNbPolyhedrons; }
 
 protected:
@@ -94,7 +97,7 @@ private:
   int myNbTetras  , myNbQuadTetras  ;
   int myNbHexas   , myNbQuadHexas,    myNbTriQuadHexas;
   int myNbPyramids, myNbQuadPyramids;
-  int myNbPrisms  , myNbQuadPrisms  ;
+  int myNbPrisms  , myNbQuadPrisms,   myNbBiQuadPrisms;
   int myNbHexPrism;
   int myNbPolyhedrons;
 
@@ -113,7 +116,7 @@ inline SMDS_MeshInfo::SMDS_MeshInfo():
   myNbTetras     (0), myNbQuadTetras  (0),
   myNbHexas      (0), myNbQuadHexas   (0), myNbTriQuadHexas(0),
   myNbPyramids   (0), myNbQuadPyramids(0),
-  myNbPrisms     (0), myNbQuadPrisms  (0),
+  myNbPrisms     (0), myNbQuadPrisms  (0), myNbBiQuadPrisms(0),
   myNbHexPrism   (0),
   myNbPolyhedrons(0)
 {
@@ -142,26 +145,30 @@ inline SMDS_MeshInfo::SMDS_MeshInfo():
   // 15  *
   // 16        *
   // 17        *
-  // 18     *
-  // 19     *
+  // 18  *
+  // 19
   // 20  *   
-  // 21     *
-  // 22     *
-  // 23     *
-  // 24     *
-  // 25
-  // 26
+  // 21
+  // 22
+  // 23
+  // 24
+  // 25     *
+  // 26     *
   // 27  *
+  // 28     *
+  // 29     *
+  // 30     *
+  // 31     *
   //
   // So to have a unique index for each type basing on nb of nodes, we use a shift:
   myShift.resize(SMDSAbs_NbElementTypes, 0);
 
-  myShift[ SMDSAbs_Face      ] = +15;// 3->18, 4->19, etc.
+  myShift[ SMDSAbs_Face      ] = +22;// 3->25, 4->26, etc.
   myShift[ SMDSAbs_Edge      ] = +14;// 2->16, 3->17
   myShift[ SMDSAbs_0DElement ] = +2; // 1->3
   myShift[ SMDSAbs_Ball      ] = +1; // 1->2
 
-  myNb.resize( index( SMDSAbs_Volume,27 ) + 1, NULL);
+  myNb.resize( index( SMDSAbs_Face,9 ) + 1, NULL);
 
   myNb[ index( SMDSAbs_Node,1 )] = & myNbNodes;
   myNb[ index( SMDSAbs_0DElement,1 )] = & myNb0DElements;
@@ -185,6 +192,7 @@ inline SMDS_MeshInfo::SMDS_MeshInfo():
   myNb[ index( SMDSAbs_Volume, 12)] = & myNbHexPrism;
   myNb[ index( SMDSAbs_Volume, 13)] = & myNbQuadPyramids;
   myNb[ index( SMDSAbs_Volume, 15)] = & myNbQuadPrisms;  
+  myNb[ index( SMDSAbs_Volume, 18)] = & myNbBiQuadPrisms;
   myNb[ index( SMDSAbs_Volume, 20)] = & myNbQuadHexas;   
   myNb[ index( SMDSAbs_Volume, 27)] = & myNbTriQuadHexas;   
 }
@@ -280,7 +288,7 @@ SMDS_MeshInfo::NbPyramids(SMDSAbs_ElementOrder order) const
 
 inline int  // NbPrisms
 SMDS_MeshInfo::NbPrisms  (SMDSAbs_ElementOrder order) const
-{ return order == ORDER_ANY ? myNbPrisms+myNbQuadPrisms : order == ORDER_LINEAR ? myNbPrisms : myNbQuadPrisms; }
+{ return order == ORDER_ANY ? myNbPrisms+myNbQuadPrisms+myNbBiQuadPrisms: order == ORDER_LINEAR ? myNbPrisms : myNbQuadPrisms+myNbBiQuadPrisms; }
 
 inline int  // NbHexPrisms
 SMDS_MeshInfo::NbHexPrisms  (SMDSAbs_ElementOrder order) const
@@ -297,7 +305,7 @@ SMDS_MeshInfo::NbElements(SMDSAbs_ElementType type) const
     break;
   case SMDSAbs_Volume:
     nb = ( myNbTetras+     myNbPyramids+     myNbPrisms+     myNbHexas+     myNbHexPrism+
-           myNbQuadTetras+ myNbQuadPyramids+ myNbQuadPrisms+ myNbQuadHexas+ myNbTriQuadHexas+
+           myNbQuadTetras+ myNbQuadPyramids+ myNbQuadPrisms+ myNbBiQuadPrisms + myNbQuadHexas+ myNbTriQuadHexas+
            myNbPolyhedrons );
     break;
   case SMDSAbs_Face:
@@ -345,6 +353,7 @@ SMDS_MeshInfo::NbEntities(SMDSAbs_EntityType type) const
   case SMDSEntity_TriQuad_Hexa:     return myNbTriQuadHexas;
   case SMDSEntity_Penta:            return myNbPrisms;
   case SMDSEntity_Quad_Penta:       return myNbQuadPrisms;
+  case SMDSEntity_BiQuad_Penta:     return myNbBiQuadPrisms;
   case SMDSEntity_Hexagonal_Prism:  return myNbHexPrism;
   case SMDSEntity_Polyhedra:        return myNbPolyhedrons;
   case SMDSEntity_0D:               return myNb0DElements;
@@ -383,7 +392,8 @@ SMDS_MeshInfo::NbElementsOfGeom(SMDSAbs_GeometryType geom) const
                                          myNbQuadHexas +
                                          myNbTriQuadHexas);
   case SMDSGeom_PENTA:           return (myNbPrisms +
-                                         myNbQuadPrisms);
+                                         myNbQuadPrisms +
+                                         myNbBiQuadPrisms);
   case SMDSGeom_HEXAGONAL_PRISM: return myNbHexPrism;
   case SMDSGeom_POLYHEDRA:       return myNbPolyhedrons;
     // Discrete:
@@ -414,6 +424,7 @@ SMDS_MeshInfo::setNb(const SMDSAbs_EntityType geomType, const int nb)
   case SMDSEntity_Quad_Edge:        myNbQuadEdges         = nb; break;
   case SMDSEntity_Quad_Hexa:        myNbQuadHexas         = nb; break;
   case SMDSEntity_Quad_Penta:       myNbQuadPrisms        = nb; break;
+  case SMDSEntity_BiQuad_Penta:     myNbBiQuadPrisms      = nb; break;
   case SMDSEntity_Quad_Pyramid:     myNbQuadPyramids      = nb; break;
   case SMDSEntity_Quad_Quadrangle:  myNbQuadQuadrangles   = nb; break;
   case SMDSEntity_Quad_Tetra:       myNbQuadTetras        = nb; break;
index 92da9c6f1bdf084977edf4f4fd210d48519bd2d8..f9c689a1717248393df31e63a8d05bd0260fc2b5 100644 (file)
@@ -381,6 +381,7 @@ SMDSAbs_EntityType SMDS_QuadraticVolumeOfNodes::GetEntityType() const
   case 10: aType = SMDSEntity_Quad_Tetra;   break;
   case 13: aType = SMDSEntity_Quad_Pyramid; break;
   case 15: aType = SMDSEntity_Quad_Penta;   break;
+  case 18: aType = SMDSEntity_BiQuad_Penta; break;
   case 20:
   default: aType = SMDSEntity_Quad_Hexa;    break;
   }
index 2fc70ee8783d36959448b986e36ac6e893c6c347..a0f0d378425d14c48c1fda1433c6f832f1bcdb5a 100644 (file)
@@ -115,6 +115,7 @@ SMDS_VtkCellIteratorToUNV::SMDS_VtkCellIteratorToUNV(SMDS_Mesh* mesh, int vtkCel
     break;
   }
   case SMDSEntity_Quad_Penta:
+  case SMDSEntity_BiQuad_Penta: //TODO: check
   {
     static int id[] = { 0, 8, 2, 7, 1, 6, 12, 14, 13, 3, 11, 5, 10, 4, 9 };
     ids = id;
index 8f66ff0846973bd929cc1d4dcebb6f0ee000e3c9..ecbcd928d2cca5c255a0166069cf4342488acc7f 100644 (file)
@@ -45,16 +45,17 @@ void SMDS_VtkVolume::init(const std::vector<vtkIdType>& nodeIds, SMDS_Mesh* mesh
   vtkIdType aType = VTK_TETRA;
   switch (nodeIds.size()) // cases are in order of usage frequency
   {
-    case 4:  aType = VTK_TETRA;                  break;
-    case 8:  aType = VTK_HEXAHEDRON;             break;
-    case 5:  aType = VTK_PYRAMID;                break;
-    case 6:  aType = VTK_WEDGE;                  break;
-    case 10: aType = VTK_QUADRATIC_TETRA;        break;
-    case 20: aType = VTK_QUADRATIC_HEXAHEDRON;   break;
-    case 13: aType = VTK_QUADRATIC_PYRAMID;      break;
-    case 15: aType = VTK_QUADRATIC_WEDGE;        break;
-    case 12: aType = VTK_HEXAGONAL_PRISM;        break;
-    case 27: aType = VTK_TRIQUADRATIC_HEXAHEDRON;break;
+    case 4:  aType = VTK_TETRA;                        break;
+    case 8:  aType = VTK_HEXAHEDRON;                   break;
+    case 5:  aType = VTK_PYRAMID;                      break;
+    case 6:  aType = VTK_WEDGE;                        break;
+    case 10: aType = VTK_QUADRATIC_TETRA;              break;
+    case 20: aType = VTK_QUADRATIC_HEXAHEDRON;         break;
+    case 13: aType = VTK_QUADRATIC_PYRAMID;            break;
+    case 15: aType = VTK_QUADRATIC_WEDGE;              break;
+    case 18: aType = VTK_BIQUADRATIC_QUADRATIC_WEDGE;  break;
+    case 12: aType = VTK_HEXAGONAL_PRISM;              break;
+    case 27: aType = VTK_TRIQUADRATIC_HEXAHEDRON;      break;
     default: aType = VTK_HEXAHEDRON;
   }
   myVtkID = mesh->getGrid()->InsertNextLinkedCell(aType, nodeIds.size(), (vtkIdType *) &nodeIds[0]);
@@ -169,6 +170,7 @@ int SMDS_VtkVolume::NbFaces() const
     case VTK_WEDGE:
     case VTK_QUADRATIC_PYRAMID:
     case VTK_QUADRATIC_WEDGE:
+    case VTK_BIQUADRATIC_QUADRATIC_WEDGE:
       nbFaces = 5;
       break;
     case VTK_HEXAHEDRON:
@@ -239,6 +241,7 @@ int SMDS_VtkVolume::NbEdges() const
       break;
     case VTK_WEDGE:
     case VTK_QUADRATIC_WEDGE:
+    case VTK_BIQUADRATIC_QUADRATIC_WEDGE:
       nbEdges = 9;
       break;
     case VTK_HEXAHEDRON:
@@ -467,6 +470,7 @@ bool SMDS_VtkVolume::IsQuadratic() const
     case VTK_QUADRATIC_TETRA:
     case VTK_QUADRATIC_PYRAMID:
     case VTK_QUADRATIC_WEDGE:
+    case VTK_BIQUADRATIC_QUADRATIC_WEDGE:
     case VTK_QUADRATIC_HEXAHEDRON:
     case VTK_TRIQUADRATIC_HEXAHEDRON:
       return true;
@@ -497,6 +501,7 @@ bool SMDS_VtkVolume::IsMediumNode(const SMDS_MeshNode* node) const
       rankFirstMedium = 5; // medium nodes are of rank 5 to 12
       break;
     case VTK_QUADRATIC_WEDGE:
+    case VTK_BIQUADRATIC_QUADRATIC_WEDGE:
       rankFirstMedium = 6; // medium nodes are of rank 6 to 14
       break;
     case VTK_QUADRATIC_HEXAHEDRON:
@@ -532,11 +537,12 @@ int SMDS_VtkVolume::NbCornerNodes() const
   vtkIdType aVtkType = grid->GetCellType(myVtkID);
   switch (aVtkType)
   {
-  case VTK_QUADRATIC_TETRA:         return 4;
-  case VTK_QUADRATIC_PYRAMID:       return 5;
-  case VTK_QUADRATIC_WEDGE:         return 6;
+  case VTK_QUADRATIC_TETRA:             return 4;
+  case VTK_QUADRATIC_PYRAMID:           return 5;
+  case VTK_QUADRATIC_WEDGE:
+  case VTK_BIQUADRATIC_QUADRATIC_WEDGE: return 6;
   case VTK_QUADRATIC_HEXAHEDRON:
-  case VTK_TRIQUADRATIC_HEXAHEDRON: return 8;
+  case VTK_TRIQUADRATIC_HEXAHEDRON:     return 8;
   default:;
   }
   return NbNodes();
@@ -571,6 +577,9 @@ SMDSAbs_EntityType SMDS_VtkVolume::GetEntityType() const
     case VTK_QUADRATIC_WEDGE:
       aType = SMDSEntity_Quad_Penta;
       break;
+    case VTK_BIQUADRATIC_QUADRATIC_WEDGE:
+      aType = SMDSEntity_BiQuad_Penta;
+      break;
     case VTK_QUADRATIC_HEXAHEDRON:
       aType = SMDSEntity_Quad_Hexa;
       break;
@@ -608,6 +617,7 @@ SMDSAbs_GeometryType SMDS_VtkVolume::GetGeomType() const
       break;
     case VTK_WEDGE:
     case VTK_QUADRATIC_WEDGE:
+    case VTK_BIQUADRATIC_QUADRATIC_WEDGE:
       aType = SMDSGeom_PENTA;
       break;
     case VTK_HEXAHEDRON:
index 035c23c5919ccc309f758165820aa958c4cdbd78..968154d1a5fa788d2e659fc5a17f2f4e8c17fc78 100644 (file)
@@ -42,8 +42,6 @@
 #include "SMESH_TypeDefs.hxx"
 #include "SMESH_subMesh.hxx"
 
-#include <Basics_OCCTVersion.hxx>
-
 #include <BRepAdaptor_Curve.hxx>
 #include <BRepLProp.hxx>
 #include <BRep_Tool.hxx>
@@ -553,28 +551,35 @@ bool SMESH_Algo::IsStraight( const TopoDS_Edge & E,
   case GeomAbs_Hyperbola:
   case GeomAbs_Parabola:
     return false;
-  // case GeomAbs_BezierCurve:
-  // case GeomAbs_BSplineCurve:
-  // case GeomAbs_OtherCurve:
+    // case GeomAbs_BezierCurve:
+    // case GeomAbs_BSplineCurve:
+    // case GeomAbs_OtherCurve:
   default:;
   }
-  const double   f = curve.FirstParameter();
-  const double   l = curve.LastParameter();
-  const gp_Pnt  pf = curve.Value( f );
-  const gp_Pnt  pl = curve.Value( l );
-  const gp_Vec v1( pf, pl );
-  const double v1Len = v1.Magnitude();
-  if ( v1Len < std::numeric_limits< double >::min() )
+
+  // evaluate how far from a straight line connecting the curve ends
+  // stand internal points of the curve
+  double  f = curve.FirstParameter();
+  double  l = curve.LastParameter();
+  gp_Pnt pf = curve.Value( f );
+  gp_Pnt pl = curve.Value( l );
+  gp_Vec lineVec( pf, pl );
+  double lineLen2 = lineVec.SquareMagnitude();
+  if ( lineLen2 < std::numeric_limits< double >::min() )
     return false; // E seems closed
-  const double tol = Min( 10 * curve.Tolerance(), v1Len * 1e-2 );
+
+  double edgeTol = 10 * curve.Tolerance();
+  double lenTol2 = lineLen2 * 1e-4; 
+  double tol2 = Min( edgeTol * edgeTol, lenTol2 );
+
   const double nbSamples = 7;
   for ( int i = 0; i < nbSamples; ++i )
   {
-    const double  r = ( i + 1 ) / nbSamples;
-    const gp_Pnt pi = curve.Value( f * r + l * ( 1 - r ));
-    const gp_Vec vi( pf, pi );
-    const double  h = 0.5 * v1.Crossed( vi ).Magnitude() / v1Len;
-    if ( h > tol )
+    double  r = ( i + 1 ) / nbSamples;
+    gp_Pnt pi = curve.Value( f * r + l * ( 1 - r ));
+    gp_Vec vi( pf, pi );
+    double h2 = lineVec.Crossed( vi ).SquareMagnitude() / lineLen2;
+    if ( h2 > tol2 )
       return false;
   }
   return true;
@@ -852,6 +857,16 @@ bool SMESH_Algo::Compute(SMESH_Mesh & /*aMesh*/, SMESH_MesherHelper* /*aHelper*/
   return error( COMPERR_BAD_INPUT_MESH, "Mesh built on shape expected");
 }
 
+//=======================================================================
+//function : IsApplicableToShape
+//purpose  : Return true if the algorithm can mesh a given shape
+//=======================================================================
+
+bool SMESH_Algo::IsApplicableToShape(const TopoDS_Shape & shape, bool toCheckAll) const
+{
+  return true;
+}
+
 //=======================================================================
 //function : CancelCompute
 //purpose  : Sets _computeCanceled to true. It's usage depends on
index d4c8f3e877aa50143fae1dc2e54a8b328fa497c4..ba8c2d356f0a3aad3da622548fbdfcf9405111b6 100644 (file)
@@ -165,6 +165,15 @@ class SMESH_EXPORT SMESH_Algo : public SMESH_Hypothesis
    */
   virtual bool Compute(SMESH_Mesh & aMesh, SMESH_MesherHelper* aHelper);
 
+  /*!
+   * \brief Return true if the algorithm can mesh a given shape
+   *  \param [in] aShape - shape to check
+   *  \param [in] toCheckAll - if true, this check returns OK if all shapes are OK,
+   *              else, returns OK if at least one shape is OK
+   *  \retval bool - \c true by default
+   */
+  virtual bool IsApplicableToShape(const TopoDS_Shape & shape, bool toCheckAll) const;
+
   /*!
    * \brief Sets _computeCanceled to true. It's usage depends on
    *        implementation of a particular mesher.
index 893a28aba659e6f8fbfb93475a251acddc4c0b97..7de8ef36ffca63ee8462cafc015fe6dec359db55 100644 (file)
@@ -1402,6 +1402,7 @@ void SMESH_Mesh::ExportMED(const char *        file,
                            bool                theAllElemsToGroup)
   throw(SALOME_Exception)
 {
+  //MESSAGE("MED_VERSION:"<< theVersion);
   SMESH_TRY;
 
   DriverMED_W_SMESHDS_Mesh myWriter;
@@ -1537,6 +1538,7 @@ void SMESH_Mesh::ExportUNV(const char *        file,
   myWriter.SetMeshId(_id);
   //  myWriter.SetGroups(_mapGroup);
 
+  // pass group names to SMESHDS
   if ( !meshPart )
   {
     for ( map<int, SMESH_Group*>::iterator it = _mapGroup.begin(); it != _mapGroup.end(); it++ ) {
@@ -1581,17 +1583,37 @@ void SMESH_Mesh::ExportSTL(const char *        file,
 
 void SMESH_Mesh::ExportCGNS(const char *        file,
                             const SMESHDS_Mesh* meshDS,
-                            const char *        meshName)
+                            const char *        meshName,
+                            const bool          groupElemsByType)
 {
   int res = Driver_Mesh::DRS_FAIL;
+
+  // pass group names to SMESHDS
+  for ( map<int, SMESH_Group*>::iterator it = _mapGroup.begin(); it != _mapGroup.end(); it++ ) {
+    SMESH_Group*       group   = it->second;
+    SMESHDS_GroupBase* groupDS = group->GetGroupDS();
+    if ( groupDS ) {
+      string groupName = group->GetName();
+      groupDS->SetStoreName( groupName.c_str() );
+    }
+  }
 #ifdef WITH_CGNS
+
   DriverCGNS_Write myWriter;
   myWriter.SetFile( file );
   myWriter.SetMesh( const_cast<SMESHDS_Mesh*>( meshDS ));
   myWriter.SetMeshName( SMESH_Comment("Mesh_") << meshDS->GetPersistentId());
   if ( meshName && meshName[0] )
     myWriter.SetMeshName( meshName );
+  myWriter.SetElementsByType( groupElemsByType );
   res = myWriter.Perform();
+  if ( res != Driver_Mesh::DRS_OK )
+  {
+    SMESH_ComputeErrorPtr err = myWriter.GetError();
+    if ( err && !err->IsOK() && !err->myComment.empty() )
+      throw SALOME_Exception(("Export failed: " + err->myComment ).c_str() );
+  }
+
 #endif
   if ( res != Driver_Mesh::DRS_OK )
     throw SALOME_Exception("Export failed");
@@ -1869,6 +1891,19 @@ int SMESH_Mesh::NbPrisms(SMDSAbs_ElementOrder order) const throw(SALOME_Exceptio
   return _myMeshDS->GetMeshInfo().NbPrisms(order);
 }
 
+int SMESH_Mesh::NbQuadPrisms() const throw (SALOME_Exception)
+{
+  Unexpect aCatch(SalomeException);
+  return _myMeshDS->GetMeshInfo().NbQuadPrisms();
+}
+
+int SMESH_Mesh::NbBiQuadPrisms() const throw (SALOME_Exception)
+{
+  Unexpect aCatch(SalomeException);
+  return _myMeshDS->GetMeshInfo().NbBiQuadPrisms();
+}
+
+
 //================================================================================
 /*!
  * \brief  Return number of hexagonal prisms in the mesh
index a8ec5dfae4e0fdfc1762cd981c82ddcccc53dea1..054616c5e361ec3833fe375d482a1bb211f33142 100644 (file)
@@ -267,7 +267,8 @@ class SMESH_EXPORT SMESH_Mesh
                  const SMESHDS_Mesh* meshPart = 0) throw(SALOME_Exception);
   void ExportCGNS(const char *        file,
                   const SMESHDS_Mesh* mesh,
-                  const char *        meshName = 0);
+                  const char *        meshName = 0,
+                  const bool          groupElemsByType = false);
   void ExportGMF(const char *        file,
                  const SMESHDS_Mesh* mesh,
                  bool                withRequiredGroups = true );
@@ -296,6 +297,8 @@ class SMESH_EXPORT SMESH_Mesh
   int NbTriQuadraticHexas() const throw(SALOME_Exception);
   int NbPyramids(SMDSAbs_ElementOrder order = ORDER_ANY) const throw(SALOME_Exception);
   int NbPrisms(SMDSAbs_ElementOrder order = ORDER_ANY) const throw(SALOME_Exception);
+  int NbQuadPrisms() const throw(SALOME_Exception);
+  int NbBiQuadPrisms() const throw(SALOME_Exception);
   int NbHexagonalPrisms() const throw(SALOME_Exception);
   int NbPolyhedrons() const throw(SALOME_Exception);
   
index 1f343b1c4233af0670e82e8529895fbedee6afb6..83066678d521b6a2a14d49571c42920c97972e1c 100644 (file)
@@ -46,8 +46,6 @@
 #include "SMESH_OctreeNode.hxx"
 #include "SMESH_subMesh.hxx"
 
-#include <Basics_OCCTVersion.hxx>
-
 #include "utilities.h"
 #include "chrono.hxx"
 
@@ -1914,6 +1912,7 @@ namespace
         break;
       case SMDSEntity_Penta:
       case SMDSEntity_Quad_Penta:
+      case SMDSEntity_BiQuad_Penta:
         connVariants = thePentaTo3; nbTet = 3; nbVariants = 6;
         break;
       default:
@@ -7482,8 +7481,8 @@ void SMESH_MeshEditor::MergeNodes (TListOfListOfNodes & theGroupsOfNodes,
   }
 
   // Remove bad elements, then equal nodes (order important)
-  Remove( rmElemIds, false );
-  Remove( rmNodeIds, true );
+  Remove( rmElemIds, /*isNodes=*/false );
+  Remove( rmNodeIds, /*isNodes=*/true );
 
   return;
 }
@@ -7553,14 +7552,14 @@ bool SMESH_MeshEditor::applyMerge( const SMDS_MeshElement* elem,
     toRemove = true;
     nbResElems = 0;
 
-    if ( elem->IsQuadratic() && newElemDefs[0].myType == SMDSAbs_Face && nbNodes > 6 )
+    if ( newElemDefs[0].myIsQuad && newElemDefs[0].myType == SMDSAbs_Face && nbNodes > 6 )
     {
       // if corner nodes stick, remove medium nodes between them from uniqueNodes
       int nbCorners = nbNodes / 2;
       for ( int iCur = 0; iCur < nbCorners; ++iCur )
       {
-        int iPrev = ( iCur + 1 ) % nbCorners;
-        if ( curNodes[ iCur ] == curNodes[ iPrev ] ) // corners stick
+        int iNext = ( iCur + 1 ) % nbCorners;
+        if ( curNodes[ iCur ] == curNodes[ iNext ] ) // corners stick
         {
           int iMedium = iCur + nbCorners;
           vector< const SMDS_MeshNode* >::iterator i =
@@ -7711,11 +7710,9 @@ bool SMESH_MeshEditor::applyMerge( const SMDS_MeshElement* elem,
       //    |       |
       //    +---+---+
       //   0    7    3
-      if (( nbUniqueNodes == 7 && nbRepl == 2 && iRepl[1] != 8 ) &&
-          (( iRepl[0] == 1 && iRepl[1] == 4 && curNodes[1] == curNodes[0] ) ||
-           ( iRepl[0] == 2 && iRepl[1] == 5 && curNodes[2] == curNodes[1] ) ||
-           ( iRepl[0] == 3 && iRepl[1] == 6 && curNodes[3] == curNodes[2] ) ||
-           ( iRepl[0] == 3 && iRepl[1] == 7 && curNodes[3] == curNodes[0] )))
+      if ( nbUniqueNodes == 7 &&
+           iRepl[0] < 4       &&
+           ( nbRepl == 1 || iRepl[1] != 8 ))
       {
         toRemove = false;
       }
@@ -9231,6 +9228,7 @@ int SMESH_MeshEditor::convertElemToQuadratic(SMESHDS_SubMesh *   theSm,
                                              SMESH_MesherHelper& theHelper,
                                              const bool          theForce3d)
 {
+  //MESSAGE("convertElemToQuadratic");
   int nbElem = 0;
   if( !theSm ) return nbElem;
 
@@ -9256,18 +9254,20 @@ int SMESH_MeshEditor::convertElemToQuadratic(SMESHDS_SubMesh *   theSm,
       case SMDSEntity_Quad_Triangle:
       case SMDSEntity_Quad_Quadrangle:
       case SMDSEntity_Quad_Hexa:
+      case SMDSEntity_Quad_Penta:
         alreadyOK = !theHelper.GetIsBiQuadratic(); break;
 
       case SMDSEntity_BiQuad_Triangle:
       case SMDSEntity_BiQuad_Quadrangle:
       case SMDSEntity_TriQuad_Hexa:
+      case SMDSEntity_BiQuad_Penta:
         alreadyOK = theHelper.GetIsBiQuadratic();
         hasCentralNodes = true;
         break;
       default:
         alreadyOK = true;
       }
-      // take into account already present modium nodes
+      // take into account already present medium nodes
       switch ( aType ) {
       case SMDSAbs_Volume:
         theHelper.AddTLinks( static_cast< const SMDS_MeshVolume* >( elem )); break;
@@ -9334,6 +9334,8 @@ int SMESH_MeshEditor::convertElemToQuadratic(SMESHDS_SubMesh *   theSm,
           NewElem = theHelper.AddVolume(nodes[0], nodes[1], nodes[2], nodes[3], nodes[4], id, theForce3d);
           break;
         case SMDSEntity_Penta:
+        case SMDSEntity_Quad_Penta:
+        case SMDSEntity_BiQuad_Penta:
           NewElem = theHelper.AddVolume(nodes[0], nodes[1], nodes[2], nodes[3], nodes[4], nodes[5], id, theForce3d);
           break;
         case SMDSEntity_Hexa:
@@ -9364,6 +9366,7 @@ int SMESH_MeshEditor::convertElemToQuadratic(SMESHDS_SubMesh *   theSm,
 
 void SMESH_MeshEditor::ConvertToQuadratic(const bool theForce3d, const bool theToBiQuad)
 {
+  //MESSAGE("ConvertToQuadratic "<< theForce3d << " " << theToBiQuad);
   SMESHDS_Mesh* meshDS = GetMeshDS();
 
   SMESH_MesherHelper aHelper(*myMesh);
@@ -9491,6 +9494,8 @@ void SMESH_MeshEditor::ConvertToQuadratic(const bool theForce3d, const bool theT
         {
         case SMDSEntity_Quad_Hexa:    alreadyOK = !theToBiQuad; break;
         case SMDSEntity_TriQuad_Hexa: alreadyOK = theToBiQuad; break;
+        case SMDSEntity_Quad_Penta:   alreadyOK = !theToBiQuad; break;
+        case SMDSEntity_BiQuad_Penta: alreadyOK = theToBiQuad; break;
         default:                      alreadyOK = true;
         }
         if ( alreadyOK )
@@ -9528,8 +9533,13 @@ void SMESH_MeshEditor::ConvertToQuadratic(const bool theForce3d, const bool theT
                                       nodes[3], nodes[4], id, theForce3d);
         break;
       case SMDSEntity_Penta:
+      case SMDSEntity_Quad_Penta:
+      case SMDSEntity_BiQuad_Penta:
         NewVolume = aHelper.AddVolume(nodes[0], nodes[1], nodes[2],
                                       nodes[3], nodes[4], nodes[5], id, theForce3d);
+        for ( size_t i = 15; i < nodes.size(); ++i ) // rm central nodes
+          if ( nodes[i]->NbInverseElements() == 0 )
+            GetMeshDS()->RemoveFreeNode( nodes[i], /*sm=*/0, /*fromGroups=*/true );
         break;
       case SMDSEntity_Hexagonal_Prism:
       default:
index e03128dc84d92994c16584069d702820e70982b1..022e091ba698440bc1e2596e219b55ba2871023a 100644 (file)
@@ -824,7 +824,7 @@ bool SMESH_MesherHelper::CheckNodeUV(const TopoDS_Face&   F,
         MESSAGE( "SMESH_MesherHelper::CheckNodeUV() failed to project" );
         return false;
       }
-      Quantity_Parameter U,V;
+      Standard_Real U,V;
       projector.LowerDistanceParameters(U,V);
       uv.SetCoord( U,V );
       surfPnt = surface->Value( U, V );
@@ -1130,7 +1130,7 @@ bool SMESH_MesherHelper::CheckNodeU(const TopoDS_Edge&   E,
           MESSAGE( "SMESH_MesherHelper::CheckNodeU() failed to project" );
           return false;
         }
-        Quantity_Parameter U = projector->LowerDistanceParameter();
+        Standard_Real U = projector->LowerDistanceParameter();
         u = double( U );
         curvPnt = curve->Value( u );
         dist = nodePnt.Distance( curvPnt );
@@ -2179,13 +2179,30 @@ SMDS_MeshVolume* SMESH_MesherHelper::AddVolume(const SMDS_MeshNode* n1,
     const SMDS_MeshNode* n14 = GetMediumNode( n1, n4, force3d, TopAbs_SOLID );
     const SMDS_MeshNode* n25 = GetMediumNode( n2, n5, force3d, TopAbs_SOLID );
     const SMDS_MeshNode* n36 = GetMediumNode( n3, n6, force3d, TopAbs_SOLID );
+    if ( myCreateBiQuadratic )
+    {
+      const SMDS_MeshNode* n1245 = GetCentralNode( n1,n2,n4,n5,n12,n25,n45,n14,force3d );
+      const SMDS_MeshNode* n1346 = GetCentralNode( n1,n3,n4,n6,n31,n36,n64,n14,force3d );
+      const SMDS_MeshNode* n2356 = GetCentralNode( n2,n3,n6,n5,n23,n36,n56,n25,force3d );
 
-    if(id)
-      elem = meshDS->AddVolumeWithID(n1, n2, n3, n4, n5, n6,
-                                     n12, n23, n31, n45, n56, n64, n14, n25, n36, id);
+      if(id)
+        elem = meshDS->AddVolumeWithID(n1, n2, n3, n4, n5, n6,
+                                       n12, n23, n31, n45, n56, n64, n14, n25, n36,
+                                       n1245, n2356, n1346, id);
+      else
+        elem = meshDS->AddVolume(n1, n2, n3, n4, n5, n6,
+                                 n12, n23, n31, n45, n56, n64, n14, n25, n36,
+                                 n1245, n2356, n1346);
+    }
     else
-      elem = meshDS->AddVolume(n1, n2, n3, n4, n5, n6,
-                               n12, n23, n31, n45, n56, n64, n14, n25, n36);
+      {
+        if(id)
+          elem = meshDS->AddVolumeWithID(n1, n2, n3, n4, n5, n6,
+                                         n12, n23, n31, n45, n56, n64, n14, n25, n36, id);
+        else
+          elem = meshDS->AddVolume(n1, n2, n3, n4, n5, n6,
+                                   n12, n23, n31, n45, n56, n64, n14, n25, n36);
+      }
   }
   if ( mySetElemOnShape && myShapeID > 0 )
     meshDS->SetMeshElementOnShape( elem, myShapeID );
@@ -2669,7 +2686,7 @@ bool SMESH_MesherHelper::LoadNodeColumns(TParam2ColumnMap &            theParam2
   }
 
   // nb rows of nodes
-  size_t prevNbRows     = theParam2ColumnMap.begin()->second.size(); // current, at least 1 here
+  size_t prevNbRows   = theParam2ColumnMap.begin()->second.size(); // current, at least 1 here
   size_t expectNbRows = faceSubMesh->NbElements() / ( theParam2ColumnMap.size()-1 ); // to be added
 
   // fill theParam2ColumnMap column by column by passing from nodes on
@@ -4866,6 +4883,7 @@ namespace { // Structures used by FixQuadraticElements()
 void SMESH_MesherHelper::FixQuadraticElements(SMESH_ComputeErrorPtr& compError,
                                               bool                   volumeOnly)
 {
+  //MESSAGE("FixQuadraticElements " << volumeOnly);
   // setenv NO_FixQuadraticElements to know if FixQuadraticElements() is guilty of bad conversion
   if ( getenv("NO_FixQuadraticElements") )
     return;
@@ -4907,6 +4925,7 @@ void SMESH_MesherHelper::FixQuadraticElements(SMESH_ComputeErrorPtr& compError,
     nbfaces = faces.Extent(); /*avoid "unused varianbles": */ nbfaces++, nbfaces--; 
 #endif
     for ( TopTools_MapIteratorOfMapOfShape fIt( faces ); fIt.More(); fIt.Next() ) {
+      MESSAGE("FIX FACE " << nbfaces-- << " #" << GetMeshDS()->ShapeToIndex(fIt.Key()));
       MSG("FIX FACE " << nbfaces-- << " #" << GetMeshDS()->ShapeToIndex(fIt.Key()));
       SMESH_MesherHelper h(*myMesh);
       h.SetSubShape( fIt.Key() );
@@ -5263,10 +5282,11 @@ void SMESH_MesherHelper::FixQuadraticElements(SMESH_ComputeErrorPtr& compError,
   // 4. Move nodes
   // -------------
 
-  TIDSortedElemSet biQuadQuas, biQuadTris, triQuadHexa;
+  TIDSortedElemSet biQuadQuas, biQuadTris, triQuadHexa, biQuadPenta;
   const bool toFixCentralNodes = ( myMesh->NbBiQuadQuadrangles() +
                                    myMesh->NbBiQuadTriangles() +
-                                   myMesh->NbTriQuadraticHexas() );
+                                   myMesh->NbTriQuadraticHexas() +
+                                   myMesh->NbBiQuadPrisms());
   double distXYZ[4];
   faceHlp.ToFixNodeParameters( true );
 
@@ -5302,6 +5322,7 @@ void SMESH_MesherHelper::FixQuadraticElements(SMESH_ComputeErrorPtr& compError,
           case SMDSEntity_BiQuad_Quadrangle: biQuadQuas.insert( e ); break;
           case SMDSEntity_BiQuad_Triangle:   biQuadTris.insert( e ); break;
           case SMDSEntity_TriQuad_Hexa:      triQuadHexa.insert( e ); break;
+          case SMDSEntity_BiQuad_Penta:      biQuadPenta.insert( e ); break;
           default:;
           }
         }
@@ -5452,6 +5473,16 @@ void SMESH_MesherHelper::FixQuadraticElements(SMESH_ComputeErrorPtr& compError,
                              nCenterCoords.X(), nCenterCoords.Y(), nCenterCoords.Z());
     }
   }
+  // treat tri-quadratic hexahedra
+  {
+    SMDS_VolumeTool volExp;
+    TIDSortedElemSet::iterator pentIt = biQuadPenta.begin();
+    for ( ; pentIt != biQuadPenta.end(); ++pentIt )
+    {
+      MESSAGE("---");
+      volExp.Set( *pentIt, /*ignoreCentralNodes=*/false );
+    }
+  }
 #ifdef _DEBUG_
   // avoid warning: defined but not used operator<<()
   SMESH_Comment() << *links.begin() << *faces.begin();
index 0f14f5ef68d24f82f1e1c50bde6bd90a93e10de9..51564bf7820973b8b05f420c17d2a7144fdfb93e 100644 (file)
@@ -75,8 +75,6 @@
 #include <gp_XY.hxx>
 #include <gp_XYZ.hxx>
 
-#include <Basics_OCCTVersion.hxx>
-
 #include <Basics_Utils.hxx>
 #include "utilities.h"
 
@@ -602,8 +600,7 @@ bool SMESH_Pattern::Load (SMESH_Mesh*        theMesh,
 
   Extrema_GenExtPS projector;
   GeomAdaptor_Surface aSurface( BRep_Tool::Surface( face ));
-  if ( theProject || needProject )
-    projector.Initialize( aSurface, 20,20, 1e-5,1e-5 );
+  projector.Initialize( aSurface, 20,20, 1e-5,1e-5 );
 
   int iPoint = 0;
   TNodePointIDMap nodePointIDMap;
@@ -690,8 +687,28 @@ bool SMESH_Pattern::Load (SMESH_Mesh*        theMesh,
 
     myPoints.resize( nbNodes );
 
+    // care of INTERNAL VERTEXes
+    TopExp_Explorer vExp( face, TopAbs_VERTEX, TopAbs_EDGE );
+    for ( ; vExp.More(); vExp.Next() )
+    {
+      const SMDS_MeshNode* node =
+        SMESH_Algo::VertexNode( TopoDS::Vertex( vExp.Current()), aMeshDS );
+      if ( !node || node->NbInverseElements( SMDSAbs_Face ) == 0 )
+        continue;
+      myPoints.resize( ++nbNodes );
+      list< TPoint* > & fPoints = getShapePoints( face );
+      nodePointIDMap.insert( make_pair( node, iPoint ));
+      TPoint* p = &myPoints[ iPoint++ ];
+      fPoints.push_back( p );
+      gp_XY uv = helper.GetNodeUV( face, node );
+      p->myInitUV.SetCoord( uv.X(), uv.Y() );
+      p->myInitXYZ.SetCoord( p->myInitUV.X(), p->myInitUV.Y(), 0 );
+    }
+
     // Load U of points on edges
 
+    Bnd_Box2d edgesUVBox;
+
     list<int>::iterator nbEinW = myNbKeyPntInBoundary.begin();
     int iE = 0;
     vector< TopoDS_Edge > eVec;
@@ -762,6 +779,7 @@ bool SMESH_Pattern::Load (SMESH_Mesh*        theMesh,
           else
             keyPoint->myInitUV = C2d->Value( isForward ? f : l ).XY();
           keyPoint->myInitXYZ.SetCoord (keyPoint->myInitUV.X(), keyPoint->myInitUV.Y(), 0);
+          edgesUVBox.Add( gp_Pnt2d( keyPoint->myInitUV ));
         }
       }
       if ( !vPoint->empty() )
@@ -841,6 +859,7 @@ bool SMESH_Pattern::Load (SMESH_Mesh*        theMesh,
             p->myInitUV = C2d->Value( u ).XY();
           }
           p->myInitXYZ.SetCoord( p->myInitUV.X(), p->myInitUV.Y(), 0 );
+          edgesUVBox.Add( gp_Pnt2d( p->myInitUV ));
           unIt++; unRIt++;
           iPoint++;
         }
@@ -866,6 +885,7 @@ bool SMESH_Pattern::Load (SMESH_Mesh*        theMesh,
           else
             keyPoint->myInitUV = C2d->Value( isForward ? l : f ).XY();
           keyPoint->myInitXYZ.SetCoord( keyPoint->myInitUV.X(), keyPoint->myInitUV.Y(), 0 );
+          edgesUVBox.Add( gp_Pnt2d( keyPoint->myInitUV ));
         }
       }
       if ( !vPoint->empty() )
@@ -906,7 +926,7 @@ bool SMESH_Pattern::Load (SMESH_Mesh*        theMesh,
         nodePointIDMap.insert( make_pair( node, iPoint ));
         TPoint* p = &myPoints[ iPoint++ ];
         fPoints.push_back( p );
-        if ( theProject )
+        if ( theProject || edgesUVBox.IsOut( p->myInitUV ) )
           p->myInitUV = project( node, projector );
         else {
           const SMDS_FacePosition* pos =
index 22fa65b99d5e44273d574cf5b00fe4a95e25ecce..2f89997baeae95d630520b9bd3821b3e2377251a 100644 (file)
@@ -38,8 +38,6 @@
 #include "SMESH_MesherHelper.hxx"
 #include "SMESH_subMeshEventListener.hxx"
 
-#include <Basics_OCCTVersion.hxx>
-
 #include "utilities.h"
 #include "OpUtil.hxx"
 #include "Basics_Utils.hxx"
index 05aece9a630d4eaed198bd46891b714a6331b054..3c2ae95d4b3c134be9f6408940fc591f92a45402 100644 (file)
@@ -684,6 +684,43 @@ void SMESHDS_Command::AddVolume(int NewVolID, int n1, int n2,
   myIntegers.push_back(n36);
   myNumber++;
 }
+//=======================================================================
+//function : AddVolume
+//purpose  :
+//=======================================================================
+void SMESHDS_Command::AddVolume(int NewVolID, int n1, int n2,
+                                int n3, int n4, int n5,int n6,
+                                int n12, int n23, int n31,
+                                int n45, int n56, int n64,
+                                int n14, int n25, int n36,
+                                int n1245, int n2356, int n1346)
+{
+  if ( myType != SMESHDS_AddBiQuadPentahedron) {
+    MESSAGE("SMESHDS_Command::AddVolume : Bad Type");
+    return;
+  }
+  myIntegers.push_back(NewVolID);
+  myIntegers.push_back(n1);
+  myIntegers.push_back(n2);
+  myIntegers.push_back(n3);
+  myIntegers.push_back(n4);
+  myIntegers.push_back(n5);
+  myIntegers.push_back(n6);
+  myIntegers.push_back(n12);
+  myIntegers.push_back(n23);
+  myIntegers.push_back(n31);
+  myIntegers.push_back(n45);
+  myIntegers.push_back(n56);
+  myIntegers.push_back(n64);
+  myIntegers.push_back(n14);
+  myIntegers.push_back(n25);
+  myIntegers.push_back(n36);
+  myIntegers.push_back(n1245);
+  myIntegers.push_back(n2356);
+  myIntegers.push_back(n1346);
+  myNumber++;
+}
+
 
 //=======================================================================
 //function : AddVolume
@@ -735,7 +772,7 @@ void SMESHDS_Command::AddVolume(int NewVolID, int n1, int n2, int n3,
                                 int n1234,int n1256,int n2367,int n3478,
                                 int n1458,int n5678,int nCenter)
 {
-  if ( myType != SMESHDS_AddQuadHexahedron) {
+  if ( myType != SMESHDS_AddTriQuadHexa) {
     MESSAGE("SMESHDS_Command::AddVolume : Bad Type");
     return;
   }
index 799de67e2dec73815b25fbe906512c4c388d2205..4af0053dd8cbc0b3b90891b8bbd1cf7e39452667 100644 (file)
@@ -83,6 +83,12 @@ class SMESHDS_EXPORT SMESHDS_Command
                        int n12, int n23, int n31,
                        int n45, int n56, int n64,
                        int n14, int n25, int n36);
+        void AddVolume(int NewVolID, int n1, int n2, int n3,
+                       int n4, int n5, int n6,
+                       int n12, int n23, int n31,
+                       int n45, int n56, int n64,
+                       int n14, int n25, int n36,
+                       int n1245, int n2356, int n1346);
         void AddVolume(int NewVolID, int n1, int n2, int n3, int n4,
                        int n5,  int n6,  int n7,  int n8,
                        int n12, int n23, int n34, int n41,
index 1d03cc2c0f3db619728664989f3b35da7780ab55..f1a21adce2fb8f0c2d54185c996669187274b342 100644 (file)
@@ -58,6 +58,7 @@ enum SMESHDS_CommandType {
   SMESHDS_Add0DElement,
   SMESHDS_AddBiQuadTriangle,
   SMESHDS_AddBiQuadQuadrangle,
+  SMESHDS_AddBiQuadPentahedron,
   SMESHDS_AddTriQuadHexa,
   SMESHDS_AddHexagonalPrism,
   SMESHDS_AddBall
index 7d4d10fdfc9f41f8fff17b1f3db466370501b952..95a91cd0c7f5e40f09de0e75b18e9cfb528b67b2 100644 (file)
@@ -51,7 +51,7 @@ SMESHDS_GroupBase::SMESHDS_GroupBase (const int                 theID,
 
 //=============================================================================
 /*!
- *  
+ *  Don't use it!
  */
 //=============================================================================
 
index bb0bf250f413682ecf642e61fc4fd9a75bca8ce8..625e64a51f4fe4a7674b315534c7f6f16f2269dd 100644 (file)
@@ -69,7 +69,7 @@ class SMESHDS_EXPORT SMESHDS_GroupBase
   virtual SMDS_ElemIteratorPtr GetElements() const = 0;
 
   virtual int GetID (const int theIndex);
-  // use it for iterations 1..Extent()
+  // DON'T use it for iterations 1..Extent()
 
   virtual int GetTic() const = 0;
 
index e7a10d7fe1eb3ee3f20414306606c850a6caf8e3..865e700c13332585d7087bbc0cf6195ac25c0bcd 100644 (file)
@@ -1862,7 +1862,7 @@ SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
 
 //=======================================================================
 //function : AddVolume
-//purpose  : 
+//purpose  : 2nd order pentahedron (prism) with 15 nodes
 //=======================================================================
 SMDS_MeshVolume* SMESHDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
                                          const SMDS_MeshNode * n2, 
@@ -1893,7 +1893,7 @@ SMDS_MeshVolume* SMESHDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
 
 //=======================================================================
 //function : AddVolumeWithID
-//purpose  : 
+//purpose  : 2nd order pentahedron (prism) with 15 nodes
 //=======================================================================
 SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(int n1, int n2, int n3,
                                                int n4, int n5, int n6,
@@ -1909,10 +1909,96 @@ SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(int n1, int n2, int n3,
                                  n45,n56,n64,n14,n25,n36);
   return anElem;
 }
+
+//=======================================================================
+//function : AddVolumeWithID
+//purpose  : 2d order Pentahedron (prism) with 15 nodes
+//=======================================================================
+SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
+                                               const SMDS_MeshNode * n2,
+                                               const SMDS_MeshNode * n3,
+                                               const SMDS_MeshNode * n4,
+                                               const SMDS_MeshNode * n5,
+                                               const SMDS_MeshNode * n6,
+                                               const SMDS_MeshNode * n12,
+                                               const SMDS_MeshNode * n23,
+                                               const SMDS_MeshNode * n31,
+                                               const SMDS_MeshNode * n45,
+                                               const SMDS_MeshNode * n56,
+                                               const SMDS_MeshNode * n64,
+                                               const SMDS_MeshNode * n14,
+                                               const SMDS_MeshNode * n25,
+                                               const SMDS_MeshNode * n36,
+                                               int ID)
+{
+  return AddVolumeWithID(n1->GetID(), n2->GetID(), n3->GetID(),
+                         n4->GetID(), n5->GetID(), n6->GetID(),
+                         n12->GetID(), n23->GetID(), n31->GetID(),
+                         n45->GetID(), n56->GetID(), n64->GetID(),
+                         n14->GetID(), n25->GetID(), n36->GetID(),
+                         ID);
+}
+//=======================================================================
+//function : AddVolume
+//purpose  : 2nd order pentahedron (prism) with 18 nodes
+//=======================================================================
+SMDS_MeshVolume* SMESHDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
+                                         const SMDS_MeshNode * n2,
+                                         const SMDS_MeshNode * n3,
+                                         const SMDS_MeshNode * n4,
+                                         const SMDS_MeshNode * n5,
+                                         const SMDS_MeshNode * n6,
+                                         const SMDS_MeshNode * n12,
+                                         const SMDS_MeshNode * n23,
+                                         const SMDS_MeshNode * n31,
+                                         const SMDS_MeshNode * n45,
+                                         const SMDS_MeshNode * n56,
+                                         const SMDS_MeshNode * n64,
+                                         const SMDS_MeshNode * n14,
+                                         const SMDS_MeshNode * n25,
+                                         const SMDS_MeshNode * n36,
+                                         const SMDS_MeshNode * n1245,
+                                         const SMDS_MeshNode * n2356,
+                                         const SMDS_MeshNode * n1346)
+{
+  SMDS_MeshVolume *anElem = SMDS_Mesh::AddVolume(n1,n2,n3,n4,n5,n6,n12,n23,n31,
+                                                 n45,n56,n64,n14,n25,n36,
+                                                 n1245, n2356, n1346);
+  if(anElem)
+    myScript->AddVolume(anElem->GetID(), n1->GetID(), n2->GetID(),
+                        n3->GetID(), n4->GetID(), n5->GetID(), n6->GetID(),
+                        n12->GetID(), n23->GetID(), n31->GetID(),
+                        n45->GetID(), n56->GetID(), n64->GetID(),
+                        n14->GetID(), n25->GetID(), n36->GetID(),
+                        n1245->GetID(), n2356->GetID(), n1346->GetID());
+  return anElem;
+}
+
+//=======================================================================
+//function : AddVolumeWithID
+//purpose  : 2nd order pentahedron (prism) with 18 nodes
+//=======================================================================
+SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(int n1, int n2, int n3,
+                                               int n4, int n5, int n6,
+                                               int n12,int n23,int n31,
+                                               int n45,int n56,int n64,
+                                               int n14,int n25,int n36,
+                                               int n1245, int n2356, int n1346,
+                                               int ID)
+{
+  SMDS_MeshVolume *anElem = SMDS_Mesh::AddVolumeWithID(n1,n2,n3,n4,n5,n6,
+                                                       n12,n23,n31,
+                                                       n45,n56,n64,
+                                                       n14,n25,n36,
+                                                       n1245, n2356, n1346, ID);
+  if(anElem) myScript->AddVolume(ID,n1,n2,n3,n4,n5,n6,n12,n23,n31,
+                                 n45,n56,n64,n14,n25,n36, n1245, n2356, n1346);
+  return anElem;
+}
         
 //=======================================================================
 //function : AddVolumeWithID
-//purpose  : 2d order Pentahedron with 15 nodes
+//purpose  : 2d order Pentahedron with 18 nodes
 //=======================================================================
 SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
                                                const SMDS_MeshNode * n2,
@@ -1929,6 +2015,9 @@ SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
                                                const SMDS_MeshNode * n14,
                                                const SMDS_MeshNode * n25,
                                                const SMDS_MeshNode * n36,
+                                               const SMDS_MeshNode * n1245,
+                                               const SMDS_MeshNode * n2356,
+                                               const SMDS_MeshNode * n1346,
                                                int ID)
 {
   return AddVolumeWithID(n1->GetID(), n2->GetID(), n3->GetID(),
@@ -1936,7 +2025,7 @@ SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
                          n12->GetID(), n23->GetID(), n31->GetID(),
                          n45->GetID(), n56->GetID(), n64->GetID(),
                          n14->GetID(), n25->GetID(), n36->GetID(),
-                         ID);
+                         n1245->GetID(), n2356->GetID(), n1346->GetID(), ID);
 }
 
 
index 89d69e3c5c115e3fd4000dc24ceda6ee1421ec63..92f631890ed558fb02a0d17d91a74548c109ae84 100644 (file)
@@ -389,6 +389,52 @@ public:
                                      const SMDS_MeshNode * n25,
                                      const SMDS_MeshNode * n36);
 
+  // 2d order Pentahedron with 18 nodes
+  virtual SMDS_MeshVolume* AddVolumeWithID(int n1, int n2, int n3,
+                                           int n4, int n5, int n6,
+                                           int n12,int n23,int n31,
+                                           int n45,int n56,int n64,
+                                           int n14,int n25,int n36,
+                                           int n1245, int n2356, int n1346,
+                                           int ID);
+  virtual SMDS_MeshVolume* AddVolumeWithID(const SMDS_MeshNode * n1,
+                                           const SMDS_MeshNode * n2,
+                                           const SMDS_MeshNode * n3,
+                                           const SMDS_MeshNode * n4,
+                                           const SMDS_MeshNode * n5,
+                                           const SMDS_MeshNode * n6,
+                                           const SMDS_MeshNode * n12,
+                                           const SMDS_MeshNode * n23,
+                                           const SMDS_MeshNode * n31,
+                                           const SMDS_MeshNode * n45,
+                                           const SMDS_MeshNode * n56,
+                                           const SMDS_MeshNode * n64,
+                                           const SMDS_MeshNode * n14,
+                                           const SMDS_MeshNode * n25,
+                                           const SMDS_MeshNode * n36,
+                                           const SMDS_MeshNode * n1245,
+                                           const SMDS_MeshNode * n2356,
+                                           const SMDS_MeshNode * n1346,
+                                           int ID);
+  virtual SMDS_MeshVolume* AddVolume(const SMDS_MeshNode * n1,
+                                     const SMDS_MeshNode * n2,
+                                     const SMDS_MeshNode * n3,
+                                     const SMDS_MeshNode * n4,
+                                     const SMDS_MeshNode * n5,
+                                     const SMDS_MeshNode * n6,
+                                     const SMDS_MeshNode * n12,
+                                     const SMDS_MeshNode * n23,
+                                     const SMDS_MeshNode * n31,
+                                     const SMDS_MeshNode * n45,
+                                     const SMDS_MeshNode * n56,
+                                     const SMDS_MeshNode * n64,
+                                     const SMDS_MeshNode * n14,
+                                     const SMDS_MeshNode * n25,
+                                     const SMDS_MeshNode * n36,
+                                     const SMDS_MeshNode * n1245,
+                                     const SMDS_MeshNode * n2356,
+                                     const SMDS_MeshNode * n1346);
+
   // 2d order Hexahedrons with 20 nodes
   virtual SMDS_MeshVolume* AddVolumeWithID(int n1, int n2, int n3, int n4,
                                            int n5, int n6, int n7, int n8,
index f912b7682fbc9001807d357a05f4cadcd92a246d..de368f199487af36f090919471c9d7443bd1ee16 100644 (file)
@@ -550,6 +550,27 @@ void SMESHDS_Script::AddVolume(int NewVolID, int n1, int n2, int n3, int n4,
 //function : AddVolume
 //purpose  : 
 //=======================================================================
+void SMESHDS_Script::AddVolume(int NewVolID, int n1, int n2, int n3, int n4,
+                                int n5,int n6, int n12, int n23, int n31,
+                                int n45, int n56, int n64,
+                                int n14, int n25, int n36,
+                                int n1245, int n2356, int n1346)
+{
+  if(myIsEmbeddedMode){
+    myIsModified = true;
+    return;
+  }
+  getCommand(SMESHDS_AddBiQuadPentahedron)->AddVolume(NewVolID, n1,n2,n3,n4,n5,n6,
+                                                    n12, n23, n31,
+                                                    n45, n56, n64,
+                                                    n14, n25, n36,
+                                                    n1245, n2356, n1346);
+}
+
+//=======================================================================
+//function : AddVolume
+//purpose  :
+//=======================================================================
 void SMESHDS_Script::AddVolume(int NewVolID, int n1, int n2, int n3,
                                int n4, int n5, int n6, int n7, int n8,
                                int n12, int n23, int n34, int n41,
index 87a081061e5f50496fd8195302e8fb1380515b2a..7b3c2fc9c0201aaf058cb6276c528c2a1bffac4e 100644 (file)
@@ -91,6 +91,12 @@ class SMESHDS_EXPORT SMESHDS_Script
                        int n12, int n23, int n31,
                        int n45, int n56, int n64,
                        int n14, int n25, int n36);
+        void AddVolume(int NewVolID, int n1, int n2, int n3,
+                       int n4, int n5, int n6,
+                       int n12, int n23, int n31,
+                       int n45, int n56, int n64,
+                       int n14, int n25, int n36,
+                       int n1245, int n2356, int n1346);
         void AddVolume(int NewVolID, int n1, int n2, int n3, int n4,
                        int n5, int n6, int n7, int n8,
                        int n12, int n23, int n34, int n41,
index 5c2c18a7cf93eeed5f9fc17e82082a5e0fdc9ca0..5ae6a8d838e843eea57f08b348b012f29a520239 100644 (file)
 #include CORBA_CLIENT_HEADER(SALOMEDS_Attributes)
 #include CORBA_CLIENT_HEADER(SMESH_MeshEditor)
 #include CORBA_CLIENT_HEADER(SMESH_Measurements)
+#include CORBA_CLIENT_HEADER(SMESH_Mesh)
 
 // Qt includes
 // #define       INCLUDE_MENUITEM_DEF // VSR commented ????????
@@ -603,6 +604,7 @@ namespace
       notSupportedElemTypes.push_back( SMESH::Entity_Quad_Polygon );
       notSupportedElemTypes.push_back( SMESH::Entity_Quad_Pyramid );
       notSupportedElemTypes.push_back( SMESH::Entity_Quad_Penta );
+      notSupportedElemTypes.push_back( SMESH::Entity_BiQuad_Penta );
       notSupportedElemTypes.push_back( SMESH::Entity_Hexagonal_Prism );
       notSupportedElemTypes.push_back( SMESH::Entity_Polyhedra );
       notSupportedElemTypes.push_back( SMESH::Entity_Quad_Polyhedra );
@@ -626,11 +628,12 @@ namespace
         "SMESH_TETRAHEDRA","SMESH_QUADRATIC_TETRAHEDRONS","SMESH_PYRAMIDS",
         "SMESH_QUADRATIC_PYRAMIDS","SMESH_HEXAHEDRA","SMESH_QUADRATIC_HEXAHEDRONS",
         "SMESH_TRIQUADRATIC_HEXAHEDRONS","SMESH_PENTAHEDRA","SMESH_QUADRATIC_PENTAHEDRONS",
+               "SMESH_BIQUADRATIC_PENTAHEDRONS",
         "SMESH_OCTAHEDRA","SMESH_POLYEDRONS","SMESH_QUADRATIC_POLYEDRONS","SMESH_BALLS"
       };
       // is typeMsg complete? (compilation failure mains that enum SMDSAbs_EntityType changed)
       const int nbTypes = sizeof( typeMsg ) / sizeof( const char* );
-      int _assert[( nbTypes == SMESH::Entity_Last ) ? 2 : -1 ]; _assert[0]=_assert[1];
+      int _assert[( nbTypes == SMESH::Entity_Last ) ? 2 : -1 ]; _assert[0]=_assert[1]=0;
 
       QString andStr = " " + QObject::tr("SMESH_AND") + " ", comma(", ");
       for ( size_t iType = 0; iType < presentNotSupported.size(); ++iType ) {
@@ -651,7 +654,7 @@ namespace
     // Get parameters of export operation
 
     QString            aFilename;
-    SMESH::MED_VERSION aFormat = SMESH::MED_V2_2;
+    SMESH::MED_VERSION aFormat = SMESH::MED_LATEST;
     // Init the parameters with the default values
     bool aIsASCII_STL   = true;
     bool toCreateGroups = false;
@@ -684,7 +687,14 @@ namespace
     }
     else if ( isCGNS )// Export to CGNS
     {
-      SUIT_FileDlg* fd = new SUIT_FileDlg( SMESHGUI::desktop(), false, true, true );
+      const char* theByTypeResource = "cgns_group_elems_by_type";
+      toCreateGroups = SMESHGUI::resourceMgr()->booleanValue( "SMESH", theByTypeResource, false );
+
+      QStringList checkBoxes;
+      checkBoxes << QObject::tr("CGNS_EXPORT_ELEMS_BY_TYPE");
+
+      SalomeApp_CheckFileDlg* fd =
+        new SalomeApp_CheckFileDlg ( SMESHGUI::desktop(), false, checkBoxes, true, true );
       fd->setWindowTitle( aTitle );
       fd->setNameFilter( QObject::tr( "CGNS_FILES_FILTER" ) + " (*.cgns)" );
       if ( !anInitialPath.isEmpty() )
@@ -692,10 +702,13 @@ namespace
       fd->selectFile(aMeshName);
       SMESHGUI_FileValidator* fv = new SMESHGUI_FileValidator( fd );
       fd->setValidator( fv );
+      fd->SetChecked( toCreateGroups, 0 );
 
       if ( fd->exec() )
         aFilename = fd->selectedFile();
-      toOverwrite = fv->isOverwrite();
+      toOverwrite    = fv->isOverwrite();
+      toCreateGroups = fd->IsChecked(0);
+      SMESHGUI::resourceMgr()->setValue("SMESH", theByTypeResource, toCreateGroups );
 
       delete fd;
     }
@@ -729,11 +742,17 @@ namespace
     else if ( isMED || isSAUV ) // Export to MED or SAUV
     {
       QMap<QString, SMESH::MED_VERSION> aFilterMap;
-      //QString v21 (aMesh->GetVersionString(SMESH::MED_V2_1, 2));
       if ( isMED ) {
         QString v22 (aMesh->GetVersionString(SMESH::MED_V2_2, 2));
-        //aFilterMap.insert( QObject::tr( "MED_VX_FILES_FILTER" ).arg( v21 ) + " (*.med)", SMESH::MED_V2_1 );
         aFilterMap.insert( QObject::tr( "MED_VX_FILES_FILTER" ).arg( v22 ) + " (*.med)", SMESH::MED_V2_2 );
+        int minor = v22.split(".").last().toInt();
+        int vv= int(SMESH::MED_MINOR_0); // add all minor from 0 to current
+        for (int ii=0; ii<minor; ii++)
+          {
+            QString vs = aMesh->GetVersionString(SMESH::MED_VERSION(vv), 2);
+            aFilterMap.insert( QObject::tr( "MED_VX_FILES_FILTER" ).arg( vs ) + " (*.med)",  SMESH::MED_VERSION(vv));
+            vv = vv +1;
+          }
       }
       else { // isSAUV
         aFilterMap.insert("All files (*)", SMESH::MED_V2_1 );
@@ -754,7 +773,7 @@ namespace
 
       SMESHGUI_FieldSelectorWdg* fieldSelWdg = new SMESHGUI_FieldSelectorWdg();
       QList< QWidget* > wdgList;
-      if ( fieldSelWdg->GetAllFeilds( aMeshList, aFieldList ))
+      if ( fieldSelWdg->GetAllFields( aMeshList, aFieldList ))
         wdgList.append( fieldSelWdg );
 
       SalomeApp_CheckFileDlg* fd =
@@ -814,7 +833,7 @@ namespace
             }
           if( !toOverwrite ) {
             // can't append to an existing using other format
-            SMESH::MED_VERSION aVersion = SMESH::MED_V2_1;
+            SMESH::MED_VERSION aVersion = aFormat; //SMESH::MED_V2_1;
             bool isVersionOk = SMESHGUI::GetSMESHGen()->GetMEDVersion( aFilename.toUtf8().constData(), aVersion );
             if( !isVersionOk || aVersion != aFormat ) {
               int aRet = SUIT_MessageBox::warning(SMESHGUI::desktop(),
@@ -858,7 +877,7 @@ namespace
       }
       toCreateGroups = fd->IsChecked(0);
       toFindOutDim   = fd->IsChecked(1);
-      fieldSelWdg->GetSelectedFeilds();
+      fieldSelWdg->GetSelectedFields();
       if ( !fieldSelWdg->parent() )
         delete fieldSelWdg;
       delete fd;
@@ -948,7 +967,8 @@ namespace
             SMESH::SMESH_Mesh_var        aMeshItem = aMeshOrGroup->GetMesh();
             aMeshItem->ExportCGNS( aMeshOrGroup,
                                    aFilename.toUtf8().data(),
-                                   toOverwrite && aMeshIndex == 0 );
+                                   toOverwrite && aMeshIndex == 0,
+                                   toCreateGroups );
           }
         }
         else if ( isGMF )
@@ -2117,7 +2137,7 @@ bool SMESHGUI::automaticUpdate( SMESH::SMESH_IDSource_ptr theMesh,
   long nbVolumes = info[SMDSEntity_Tetra]   + info[SMDSEntity_Quad_Tetra] + 
                    info[SMDSEntity_Hexa]    + info[SMDSEntity_Quad_Hexa] + info[SMDSEntity_TriQuad_Hexa] + 
                    info[SMDSEntity_Pyramid] + info[SMDSEntity_Quad_Pyramid] + 
-                   info[SMDSEntity_Penta]   + info[SMDSEntity_Quad_Penta] + 
+                   info[SMDSEntity_Penta]   + info[SMDSEntity_Quad_Penta] + info[SMDSEntity_BiQuad_Penta] +
                    info[SMDSEntity_Polyhedra] + 
                    info[SMDSEntity_Hexagonal_Prism];
   long nbBalls   = info[SMDSEntity_Ball];
@@ -2637,9 +2657,7 @@ bool SMESHGUI::OnGUIEvent( int theCommandID )
       if(checkLock(aStudy)) break;
       SUIT_OverrideCursor wc;
       try {
-#if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
         OCC_CATCH_SIGNALS;
-#endif
         SMESH::UpdateView();
       }
       catch (std::bad_alloc) { // PAL16774 (Crash after display of many groups)
@@ -3297,6 +3315,7 @@ bool SMESHGUI::OnGUIEvent( int theCommandID )
   case SMESHOp::OpQuadraticTetrahedron:
   case SMESHOp::OpQuadraticPyramid:
   case SMESHOp::OpQuadraticPentahedron:
+  case SMESHOp::OpBiQuadraticPentahedron:
   case SMESHOp::OpQuadraticHexahedron:
   case SMESHOp::OpTriQuadraticHexahedron:
     {
@@ -3315,6 +3334,7 @@ bool SMESHGUI::OnGUIEvent( int theCommandID )
         case SMESHOp::OpQuadraticTetrahedron:   type = SMDSEntity_Quad_Tetra; break;
         case SMESHOp::OpQuadraticPyramid:       type = SMDSEntity_Quad_Pyramid; break;
         case SMESHOp::OpQuadraticPentahedron:   type = SMDSEntity_Quad_Penta; break;
+        case SMESHOp::OpBiQuadraticPentahedron: type = SMDSEntity_BiQuad_Penta; break;
         case SMESHOp::OpQuadraticHexahedron:    type = SMDSEntity_Quad_Hexa; break;
         case SMESHOp::OpTriQuadraticHexahedron: type = SMDSEntity_TriQuad_Hexa; break;
         default: break;
@@ -3947,6 +3967,7 @@ void SMESHGUI::initialize( CAM_Application* app )
   createSMESHAction( SMESHOp::OpQuadraticTetrahedron,   "QUADRATIC_TETRAHEDRON",   "ICON_DLG_QUADRATIC_TETRAHEDRON" );
   createSMESHAction( SMESHOp::OpQuadraticPyramid,       "QUADRATIC_PYRAMID",       "ICON_DLG_QUADRATIC_PYRAMID" );
   createSMESHAction( SMESHOp::OpQuadraticPentahedron,   "QUADRATIC_PENTAHEDRON",   "ICON_DLG_QUADRATIC_PENTAHEDRON" );
+  createSMESHAction( SMESHOp::OpBiQuadraticPentahedron, "BIQUADRATIC_PENTAHEDRON", "ICON_DLG_BIQUADRATIC_PENTAHEDRON" );
   createSMESHAction( SMESHOp::OpQuadraticHexahedron,    "QUADRATIC_HEXAHEDRON",    "ICON_DLG_QUADRATIC_HEXAHEDRON" );
   createSMESHAction( SMESHOp::OpTriQuadraticHexahedron, "TRIQUADRATIC_HEXAHEDRON", "ICON_DLG_TRIQUADRATIC_HEXAHEDRON" );
 
@@ -4183,6 +4204,7 @@ void SMESHGUI::initialize( CAM_Application* app )
   createMenu( SMESHOp::OpQuadraticTetrahedron,   addId, -1 );
   createMenu( SMESHOp::OpQuadraticPyramid,       addId, -1 );
   createMenu( SMESHOp::OpQuadraticPentahedron,   addId, -1 );
+  createMenu( SMESHOp::OpBiQuadraticPentahedron, addId, -1 );
   createMenu( SMESHOp::OpQuadraticHexahedron,    addId, -1 );
   createMenu( SMESHOp::OpTriQuadraticHexahedron, addId, -1 );
 
@@ -4328,6 +4350,7 @@ void SMESHGUI::initialize( CAM_Application* app )
   createTool( SMESHOp::OpQuadraticTetrahedron,   addNonElemTb );
   createTool( SMESHOp::OpQuadraticPyramid,       addNonElemTb );
   createTool( SMESHOp::OpQuadraticPentahedron,   addNonElemTb );
+  createTool( SMESHOp::OpBiQuadraticPentahedron, addNonElemTb );
   createTool( SMESHOp::OpQuadraticHexahedron,    addNonElemTb );
   createTool( SMESHOp::OpTriQuadraticHexahedron, addNonElemTb );
 
index c24dbc4b3eac838cee465990b0267b74649f2dd1..4193be407c39abb92198d6e1f6867f1f2446423f 100644 (file)
@@ -380,6 +380,9 @@ SMESHGUI_AddQuadraticElementDlg::SMESHGUI_AddQuadraticElementDlg( SMESHGUI* theM
   case SMDSEntity_Quad_Penta:
     anElementName = QString("QUADRATIC_PENTAHEDRON");
     break;
+  case SMDSEntity_BiQuad_Penta:
+    anElementName = QString("BIQUADRATIC_PENTAHEDRON");
+    break;
   case SMDSEntity_Quad_Hexa:
     anElementName = QString("QUADRATIC_HEXAHEDRON");
     break;
@@ -587,6 +590,12 @@ void SMESHGUI_AddQuadraticElementDlg::Init()
     myNbCorners = 6;
     myHelpFileName = "adding_quadratic_elements_page.html#?"; //Adding_pentahedrons
     break;
+  case SMDSEntity_BiQuad_Penta:
+    aNumRows = 9;
+    myNbCorners = 6;
+    myNbMidFaceNodes = 3;
+    myHelpFileName = "adding_quadratic_elements_page.html#?"; //Adding_pentahedrons
+    break;
   case SMDSEntity_Quad_Hexa:
     aNumRows = 12;
     myNbCorners = 8;
@@ -707,6 +716,7 @@ bool SMESHGUI_AddQuadraticElementDlg::ClickOnApply()
   case SMDSEntity_Quad_Tetra:
   case SMDSEntity_Quad_Pyramid:
   case SMDSEntity_Quad_Penta:
+  case SMDSEntity_BiQuad_Penta:
   case SMDSEntity_Quad_Hexa:
   case SMDSEntity_TriQuad_Hexa:
     for ( int row = 0; row < myNbCorners; row++ )
@@ -790,6 +800,7 @@ bool SMESHGUI_AddQuadraticElementDlg::ClickOnApply()
   case SMDSEntity_Quad_Tetra:
   case SMDSEntity_Quad_Pyramid:
   case SMDSEntity_Quad_Penta:
+  case SMDSEntity_BiQuad_Penta:
   case SMDSEntity_Quad_Hexa:
   case SMDSEntity_TriQuad_Hexa:
     anElementType = SMESH::VOLUME;
@@ -1068,6 +1079,7 @@ void SMESHGUI_AddQuadraticElementDlg::SelectionIntoArgument()
     case SMDSEntity_Quad_Tetra:
     case SMDSEntity_Quad_Pyramid:
     case SMDSEntity_Quad_Penta:
+    case SMDSEntity_BiQuad_Penta:
     case SMDSEntity_Quad_Hexa:
     case SMDSEntity_TriQuad_Hexa:
       anElementType = SMESH::VOLUME; break;
@@ -1402,6 +1414,7 @@ void SMESHGUI_AddQuadraticElementDlg::UpdateTable( bool theConersValidity )
       aLastColIds  = LastPyramidIds;
       break;
     case SMDSEntity_Quad_Penta:
+    case SMDSEntity_BiQuad_Penta:
       aFirstColIds = FirstPentahedronIds;
       aLastColIds  = LastPentahedronIds;
       break;
index 5a32503a1ae6f702a5a77476fc44675e3a1cbbc8..b762d30188e9f0455db5407600a85e5c7add84cf 100644 (file)
@@ -1232,7 +1232,7 @@ void SMESHGUI_BaseComputeOp::showComputeResult( const bool theMemoryLack,
       currentCellChanged(); // to update buttons
     }
   }
-  // show dialog and wait, becase Compute can be invoked from Preview operation
+  // show dialog and wait, because Compute can be invoked from Preview operation
   //aCompDlg->exec(); // this way it becomes modal - impossible to rotate model in the Viewer
   aCompDlg->show();
 }
@@ -1984,9 +1984,7 @@ void SMESHGUI_PrecomputeOp::onPreview()
   
   SMESH::long_array_var aShapesId = new SMESH::long_array();
   try {
-#if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
     OCC_CATCH_SIGNALS;
-#endif
       
     SMESH::MeshPreviewStruct_var previewData =
       gen->Precompute(myMesh, myMainShape, (SMESH::Dimension)dim, aShapesId);
@@ -2009,9 +2007,7 @@ void SMESHGUI_PrecomputeOp::onPreview()
   }
 
   try {
-#if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
     OCC_CATCH_SIGNALS;
-#endif
     aCompErrors = gen->GetComputeErrors( myMesh, myMainShape );
     // check if there are memory problems
     for ( CORBA::ULong i = 0; (i < aCompErrors->length()) && !memoryLack; ++i )
@@ -2227,9 +2223,7 @@ void SMESHGUI_BaseComputeOp::evaluateMesh()
     }
     SUIT_OverrideCursor aWaitCursor;
     try {
-#if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
       OCC_CATCH_SIGNALS;
-#endif
       aRes = gen->Evaluate(myMesh, myMainShape);
     }
     catch(const SALOME::SALOME_Exception & S_ex){
@@ -2237,9 +2231,7 @@ void SMESHGUI_BaseComputeOp::evaluateMesh()
     }
 
     try {
-#if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
       OCC_CATCH_SIGNALS;
-#endif
       aCompErrors = gen->GetComputeErrors( myMesh, myMainShape );
     }
     catch(const SALOME::SALOME_Exception & S_ex){
@@ -2397,7 +2389,7 @@ void SMESHGUI_BaseComputeOp::showEvaluateResult(const SMESH::long_array& theRes,
       currentCellChanged(); // to update buttons
     }
   }
-  // show dialog and wait, becase Compute can be invoked from Preview operation
+  // show dialog and wait, because Compute can be invoked from Preview operation
   //aCompDlg->exec(); // this way it becomes modal - impossible to rotate model in the Viewer
   aCompDlg->show();
 }
index 3afa881c15178f5b4a3e82a8ed7b627e900d95e9..77b0a8fe67c5ff3363075ec18a53c1f2c5c973ba 100644 (file)
@@ -332,6 +332,7 @@ SMESHGUI_ConvToQuadOp::DestinationMesh( const SMESH::SMESH_IDSource_var& idSourc
 
   bool hasBiQuad     = ( nbElemOfType[SMDSEntity_BiQuad_Triangle   ] ||
                          nbElemOfType[SMDSEntity_BiQuad_Quadrangle ] ||
+                         nbElemOfType[SMDSEntity_BiQuad_Penta      ] ||
                          nbElemOfType[SMDSEntity_TriQuad_Hexa      ] );
   bool hasLinBiQuad  = ( nbElemOfType[SMDSEntity_Triangle   ] ||
                          nbElemOfType[SMDSEntity_Quadrangle ] ||
index 5af7f78159e78780147431139fad3136f9e6f62e..14088fe1a169614ce010ba1a9fd6c30ca7aa91ac 100644 (file)
@@ -97,7 +97,7 @@ SMESHGUI_DisplayEntitiesDlg::SMESHGUI_DisplayEntitiesDlg( QWidget* parent )
   hl->addWidget( nb0DElemsLab, 0, 1 );
   my0DElemsTB->setEnabled( nbElements );
   nb0DElemsLab->setEnabled( nbElements );
-  myNbTypes += ( nbElements > 0 );
+  myNbTypes = ( nbElements > 0 );
 
   // Edges
   nbElements = myActor ? myActor->GetObject()->GetNbEntities( SMDSAbs_Edge ) : aMesh->NbEdges();
index 8b060f647c19d1c999e820f0673fac252cc3aeaf..91034498099e2bca288b7a9b63f0b97c0eb32f72 100644 (file)
@@ -86,7 +86,7 @@ SMESHGUI_FieldSelectorWdg::SMESHGUI_FieldSelectorWdg( QWidget* p )
  * \brief Retrieves all fields defined on geometry of given meshes
  */
 bool SMESHGUI_FieldSelectorWdg::
-GetAllFeilds(const QList< QPair< SMESH::SMESH_IDSource_var, QString > >& meshes,
+GetAllFields(const QList< QPair< SMESH::SMESH_IDSource_var, QString > >& meshes,
              QList< QPair< GEOM::ListOfFields_var, QString > >&          fields)
 {
   myFields = & fields;
@@ -166,7 +166,7 @@ GetAllFeilds(const QList< QPair< SMESH::SMESH_IDSource_var, QString > >& meshes,
 /*!
  * \brief Filter off not selected fields from myFields
  */
-bool SMESHGUI_FieldSelectorWdg::GetSelectedFeilds()
+bool SMESHGUI_FieldSelectorWdg::GetSelectedFields()
 {
   int nbSelected = 0;
   if ( myTree->isEnabled() )
index 8a88bf41d77954ff6eff8222a2a7afb6785f5ee7..025a4de7308b4805d8b50307d37a5af061bee136 100644 (file)
@@ -43,13 +43,13 @@ class SMESHGUI_EXPORT SMESHGUI_FieldSelectorWdg : public QGroupBox
  public:
   SMESHGUI_FieldSelectorWdg( QWidget* = 0 );
 
-  bool GetAllFeilds(const QList< QPair< SMESH::SMESH_IDSource_var, QString > >& meshes,
+  bool GetAllFields(const QList< QPair< SMESH::SMESH_IDSource_var, QString > >& meshes,
                     QList< QPair< GEOM::ListOfFields_var,          QString > >& fields);
 
-  bool GetSelectedFeilds();
+  bool GetSelectedFields();
 
  private slots:
-  
+
   void onItemCheck(QTreeWidgetItem * item, int column);
 
  private:
index 05d00338731ce65d25add9145c7a92325d96dd34..1222c4b808ce93543284befb97f59ba42284b608 100755 (executable)
 #include <SMDS_Mesh.hxx>
 #include <SMDSAbs_ElementType.hxx>
 
-OCCT_IMPLEMENT_STANDARD_RTTIEXT(SMESHGUI_Filter, VTKViewer_Filter)
-OCCT_IMPLEMENT_STANDARD_RTTIEXT(SMESHGUI_PredicateFilter, SMESHGUI_Filter)
-OCCT_IMPLEMENT_STANDARD_RTTIEXT(SMESHGUI_QuadrangleFilter, SMESHGUI_Filter)
-OCCT_IMPLEMENT_STANDARD_RTTIEXT(SMESHGUI_TriangleFilter, SMESHGUI_Filter)
-OCCT_IMPLEMENT_STANDARD_RTTIEXT(SMESHGUI_FacesFilter, SMESHGUI_Filter)
-OCCT_IMPLEMENT_STANDARD_RTTIEXT(SMESHGUI_VolumesFilter, SMESHGUI_Filter)
-OCCT_IMPLEMENT_STANDARD_RTTIEXT(SMESHGUI_VolumeShapeFilter, SMESHGUI_Filter)
+IMPLEMENT_STANDARD_RTTIEXT(SMESHGUI_Filter, VTKViewer_Filter)
+IMPLEMENT_STANDARD_RTTIEXT(SMESHGUI_PredicateFilter, SMESHGUI_Filter)
+IMPLEMENT_STANDARD_RTTIEXT(SMESHGUI_QuadrangleFilter, SMESHGUI_Filter)
+IMPLEMENT_STANDARD_RTTIEXT(SMESHGUI_TriangleFilter, SMESHGUI_Filter)
+IMPLEMENT_STANDARD_RTTIEXT(SMESHGUI_FacesFilter, SMESHGUI_Filter)
+IMPLEMENT_STANDARD_RTTIEXT(SMESHGUI_VolumesFilter, SMESHGUI_Filter)
+IMPLEMENT_STANDARD_RTTIEXT(SMESHGUI_VolumeShapeFilter, SMESHGUI_Filter)
 
 /*
   Class       : SMESHGUI_PredicateFilter
index ec36f46d6e76900d8eb64f3ccbe901e8eccdc21d..08a43c7675be5d5c608730f252b0c80ccef7a23c 100755 (executable)
@@ -70,7 +70,7 @@ public:
   Standard_EXPORT virtual bool IsObjValid( const int ) const = 0;
 
 public:
-  OCCT_DEFINE_STANDARD_RTTIEXT(SMESHGUI_Filter,VTKViewer_Filter)
+  DEFINE_STANDARD_RTTIEXT(SMESHGUI_Filter,VTKViewer_Filter)
 };
 
 /*
@@ -99,7 +99,7 @@ private:
   SMESH::Predicate_var        myPred;
 
 public:
-  OCCT_DEFINE_STANDARD_RTTIEXT(SMESHGUI_PredicateFilter,SMESHGUI_Filter)
+  DEFINE_STANDARD_RTTIEXT(SMESHGUI_PredicateFilter,SMESHGUI_Filter)
 };
 
 /*
@@ -121,7 +121,7 @@ public:
   Standard_EXPORT virtual bool IsNodeFilter() const;
 
 public:
-  OCCT_DEFINE_STANDARD_RTTIEXT(SMESHGUI_QuadrangleFilter,SMESHGUI_Filter)
+  DEFINE_STANDARD_RTTIEXT(SMESHGUI_QuadrangleFilter,SMESHGUI_Filter)
 };
 
 /*
@@ -143,7 +143,7 @@ public:
   Standard_EXPORT virtual bool IsNodeFilter() const;  
 
 public:
-  OCCT_DEFINE_STANDARD_RTTIEXT(SMESHGUI_TriangleFilter,SMESHGUI_Filter)
+  DEFINE_STANDARD_RTTIEXT(SMESHGUI_TriangleFilter,SMESHGUI_Filter)
 };
 
 /*
@@ -165,7 +165,7 @@ public:
   Standard_EXPORT virtual bool IsNodeFilter() const;  
 
 public:
-  OCCT_DEFINE_STANDARD_RTTIEXT(SMESHGUI_FacesFilter,SMESHGUI_Filter)
+  DEFINE_STANDARD_RTTIEXT(SMESHGUI_FacesFilter,SMESHGUI_Filter)
 };
 
 /*
@@ -187,7 +187,7 @@ public:
   Standard_EXPORT virtual bool IsNodeFilter() const;
 
 public:
-  OCCT_DEFINE_STANDARD_RTTIEXT(SMESHGUI_VolumesFilter,SMESHGUI_Filter)
+  DEFINE_STANDARD_RTTIEXT(SMESHGUI_VolumesFilter,SMESHGUI_Filter)
 };
 
 /*
@@ -211,7 +211,7 @@ public:
   Standard_EXPORT static int GetId( SMDSAbs_GeometryType geom );
 
 public:
-  OCCT_DEFINE_STANDARD_RTTIEXT(SMESHGUI_VolumeShapeFilter,SMESHGUI_Filter)
+  DEFINE_STANDARD_RTTIEXT(SMESHGUI_VolumeShapeFilter,SMESHGUI_Filter)
 };
 
 #endif // SMESHGUI_FILTER_H
index 4e7f6bf5ff91f1fb827ca8e6f3a2088478e904ae..6c6987c399701ee75f41b78625744014389a09c4 100755 (executable)
@@ -1753,6 +1753,7 @@ static QList<int> entityTypes( const int theType )
     typeIds.append( SMDSEntity_TriQuad_Hexa );
     typeIds.append( SMDSEntity_Penta );
     typeIds.append( SMDSEntity_Quad_Penta );
+    typeIds.append( SMDSEntity_BiQuad_Penta );
     typeIds.append( SMDSEntity_Hexagonal_Prism );
     typeIds.append( SMDSEntity_Polyhedra );
     //typeIds.append( SMDSEntity_Quad_Polyhedra );
index c7d806b7da09362543e0ff236a00ef96c5072eb5..0b2cbb975fc1fdd221592a962687deb4986afdd5 100644 (file)
@@ -1118,14 +1118,14 @@ bool SMESHGUI_GroupDlg::onApply()
   {
     if ( myFilter->_is_nil() ) return false;
 
-    if (CORBA::is_nil(myGroupOnFilter)) { // creation
+    if (CORBA::is_nil(myGroupOnFilter)) // creation
+    {
       if (myMesh->_is_nil())
         return false;
 
       myGroupOnFilter = myMesh->CreateGroupFromFilter(aType,
                                                       SMESH::toUtf8(myName->text()),
                                                       myFilter);
-
       resultGroup = SMESH::SMESH_GroupBase::_narrow( myGroupOnFilter );
       isCreation = true;
     }
@@ -1139,7 +1139,7 @@ bool SMESHGUI_GroupDlg::onApply()
     anIsOk = true;
   }
 
-  if( anIsOk )
+  if ( anIsOk )
   {
     SALOMEDS::Color aColor = getGroupColor();
     resultGroup->SetColor(aColor);
index dc1461cda8159a93ab2669695854a27dc2a2c1f7..7808f78990d978c029568a89fcfcac5a1e8287b0 100644 (file)
@@ -77,7 +77,8 @@ SMESHGUI_GroupOnShapeDlg::SMESHGUI_GroupOnShapeDlg()
 
   // Elem geom
 
-  QGroupBox* elemsGrp = new QGroupBox( tr( "SMESH_ELEMENTS" ), mainFrame() );
+  QGroupBox* elemsGrp = new QGroupBox( tr( "ELEMENTS" ), mainFrame() );
+  elemsGrp->setToolTip( tr("ELEMENTS_TOOLTIP") );
   QLabel* label = new QLabel( tr( "SMESH_GEOM" ), elemsGrp );
   myElemGeomBtn = new QPushButton( elemsGrp );
   myElemGeomBtn->setCheckable(true);
index 021e003b93ada81e5b8ac34a605df6fa074364ff..def3ff5572faf09584510e225003f46769ff9aa5 100644 (file)
 #endif
 
 #ifdef WIN32
-#define LibHandle HMODULE
-#define LoadLib( name ) LoadLibrary( name )
-#define GetProc GetProcAddress
-#define UnLoadLib( handle ) FreeLibrary( handle );
-#else
-#define LibHandle void*
-#define LoadLib( name ) dlopen( name, RTLD_LAZY | RTLD_GLOBAL )
-#define GetProc dlsym
-#define UnLoadLib( handle ) dlclose( handle );
-#endif
+ #define LibHandle HMODULE
+ #define LoadLib( name ) LoadLibrary( name )
+ #define GetProc GetProcAddress
+ #define UnLoadLib( handle ) FreeLibrary( handle );
+#else // WIN32
+ #define LibHandle void*
+ #ifdef DYNLOAD_LOCAL
+  #define LoadLib( name ) dlopen( name, RTLD_LAZY | RTLD_LOCAL )
+ #else // DYNLOAD_LOCAL
+  #define LoadLib( name ) dlopen( name, RTLD_LAZY | RTLD_GLOBAL )
+ #endif // DYNLOAD_LOCAL
+ #define GetProc dlsym
+ #define UnLoadLib( handle ) dlclose( handle );
+#endif // WIN32
 
 #ifdef _DEBUG_
 static int MYDEBUG = 0;
index b8522893ff76f0a50a75b1708994d3f4c6ce546f..7dca619fb97c75670ee3ead61eb71c461f293899 100644 (file)
@@ -153,6 +153,7 @@ vtkIdType getCellType( const SMDSAbs_ElementType theType,
     else if ( theNbNodes == 20 )  return VTK_QUADRATIC_HEXAHEDRON;
     else if ( theNbNodes == 27 )  return VTK_TRIQUADRATIC_HEXAHEDRON;
     else if ( theNbNodes == 15  ) return VTK_QUADRATIC_WEDGE;
+    else if ( theNbNodes == 18  ) return VTK_BIQUADRATIC_QUADRATIC_WEDGE;
     else if ( theNbNodes == 13  ) return VTK_QUADRATIC_PYRAMID;//VTK_CONVEX_POINT_SET;
     else return VTK_EMPTY_CELL;
 
index c2932c2032730c788df81e2b55bf9fcdc5a9576f..a05414b8c54db553d97fb2e0619d161219ad5982 100644 (file)
 
 namespace {
 
-const int SPACING      = 6;
-const int MARGIN       = 9;
-const int MAXITEMS     = 10;
-const int GROUPS_ID    = 100;
-const int SUBMESHES_ID = 200;
-const int SPACING_INFO = 2;
-
-enum InfoRole {
-  TypeRole = Qt::UserRole + 10,
-  IdRole,
-};
-
-enum InfoType {
-  NodeConnectivity = 100,
-  ElemConnectivity,
-};
+  const int SPACING      = 6;
+  const int MARGIN       = 9;
+  const int MAXITEMS     = 10;
+  const int GROUPS_ID    = 100;
+  const int SUBMESHES_ID = 200;
+  const int SPACING_INFO = 2;
+
+  const char* id_preview_resource = "id_preview_resource";
+
+  enum InfoRole {
+    TypeRole = Qt::UserRole + 10,
+    IdRole,
+  };
+
+  enum InfoType {
+    NodeConnectivity = 100,
+    ElemConnectivity,
+  };
 } // namesapce
 
 /*!
@@ -384,6 +386,8 @@ SMESHGUI_MeshInfo::SMESHGUI_MeshInfo( QWidget* parent )
   a3DPriLin->setObjectName("nbLinearPrism");
   QLabel*  a3DPriQuad   = createField();
   a3DPriQuad->setObjectName("nbQuadraticPrism");
+  QLabel*  a3DPriBiQuad   = createField();
+  a3DPriBiQuad->setObjectName("nbBiQuadraticPrism");
   QLabel*  a3DHexPriLab   = new QLabel( tr( "HEX_PRISMS_LAB" ), this );
   QLabel*  a3DHexPriTotal = createField();
   a3DHexPriTotal->setObjectName("nbHexagonalPrism");
@@ -395,7 +399,7 @@ SMESHGUI_MeshInfo::SMESHGUI_MeshInfo( QWidget* parent )
   myWidgets[ index++ ] << a3DTetLab << a3DTetTotal << a3DTetLin << a3DTetQuad;
   myWidgets[ index++ ] << a3DHexLab << a3DHexTotal << a3DHexLin << a3DHexQuad << a3DHexBiQuad;
   myWidgets[ index++ ] << a3DPyrLab << a3DPyrTotal << a3DPyrLin << a3DPyrQuad;
-  myWidgets[ index++ ] << a3DPriLab << a3DPriTotal << a3DPriLin << a3DPriQuad;
+  myWidgets[ index++ ] << a3DPriLab << a3DPriTotal << a3DPriLin << a3DPriQuad << a3DPriBiQuad;
   myWidgets[ index++ ] << a3DHexPriLab << a3DHexPriTotal;
   myWidgets[ index++ ] << a3DPolLab << a3DPolTotal;
 
@@ -489,6 +493,7 @@ SMESHGUI_MeshInfo::SMESHGUI_MeshInfo( QWidget* parent )
   l->addWidget( a3DPriTotal,  24, 1 );
   l->addWidget( a3DPriLin,    24, 2 );
   l->addWidget( a3DPriQuad,   24, 3 );
+  l->addWidget( a3DPriBiQuad, 24, 4 );
   l->addWidget( a3DHexPriLab,   25, 0 );
   l->addWidget( a3DHexPriTotal, 25, 1 );
   l->addWidget( a3DPolLab,    26, 0 );
@@ -579,10 +584,10 @@ void SMESHGUI_MeshInfo::showInfo( SMESH::SMESH_IDSource_ptr obj )
     long nbTetrahedrons  = info[SMDSEntity_Tetra]   + info[SMDSEntity_Quad_Tetra];
     long nbHexahedrons   = info[SMDSEntity_Hexa]    + info[SMDSEntity_Quad_Hexa] + info[SMDSEntity_TriQuad_Hexa];
     long nbPyramids      = info[SMDSEntity_Pyramid] + info[SMDSEntity_Quad_Pyramid];
-    long nbPrisms        = info[SMDSEntity_Penta]   + info[SMDSEntity_Quad_Penta];
+    long nbPrisms        = info[SMDSEntity_Penta]   + info[SMDSEntity_Quad_Penta] + info[SMDSEntity_BiQuad_Penta];
     long nb3DLinear      = info[SMDSEntity_Tetra]   + info[SMDSEntity_Hexa] + info[SMDSEntity_Pyramid] + info[SMDSEntity_Penta] + info[SMDSEntity_Polyhedra] + info[SMDSEntity_Hexagonal_Prism];
     long nb3DQuadratic   = info[SMDSEntity_Quad_Tetra] + info[SMDSEntity_Quad_Hexa] + info[SMDSEntity_Quad_Pyramid] + info[SMDSEntity_Quad_Penta];
-    long nb3DBiQuadratic = info[SMDSEntity_TriQuad_Hexa];
+    long nb3DBiQuadratic = info[SMDSEntity_TriQuad_Hexa] + info[SMDSEntity_BiQuad_Penta];
     long nb3DTotal       = nb3DLinear + nb3DQuadratic + nb3DBiQuadratic;
     myWidgets[i3D][iTotal]                  ->setProperty( "text", QString::number( nb3DTotal ));
     myWidgets[i3D][iLinear]                 ->setProperty( "text", QString::number( nb3DLinear ));
@@ -601,6 +606,7 @@ void SMESHGUI_MeshInfo::showInfo( SMESH::SMESH_IDSource_ptr obj )
     myWidgets[i3DPrisms][iTotal]            ->setProperty( "text", QString::number( nbPrisms ));
     myWidgets[i3DPrisms][iLinear]           ->setProperty( "text", QString::number( info[SMDSEntity_Penta] ));
     myWidgets[i3DPrisms][iQuadratic]        ->setProperty( "text", QString::number( info[SMDSEntity_Quad_Penta] ));
+    myWidgets[i3DPrisms][iBiQuadratic]      ->setProperty( "text", QString::number( info[SMDSEntity_BiQuad_Penta] ));
     myWidgets[i3DHexaPrisms][iTotal]        ->setProperty( "text", QString::number( info[SMDSEntity_Hexagonal_Prism] ));
     myWidgets[i3DPolyhedrons][iTotal]       ->setProperty( "text", QString::number( info[SMDSEntity_Polyhedra] ));
     long nbElemTotal       = info[SMDSEntity_0D] + info[SMDSEntity_Ball] + nbEdges + nb2DTotal + nb3DTotal;
@@ -1372,6 +1378,7 @@ void SMESHGUI_SimpleElemInfo::information( const QList<long>& ids )
           gtype = SMESHGUI_ElemInfo::tr( "HEXAHEDRON" ); break;
         case SMDSEntity_Penta:
         case SMDSEntity_Quad_Penta:
+        case SMDSEntity_BiQuad_Penta:
           gtype = SMESHGUI_ElemInfo::tr( "PRISM" ); break;
         case SMDSEntity_Hexagonal_Prism:
           gtype = SMESHGUI_ElemInfo::tr( "HEX_PRISM" ); break;
@@ -1894,6 +1901,7 @@ void SMESHGUI_TreeElemInfo::information( const QList<long>& ids )
           gtype = SMESHGUI_ElemInfo::tr( "HEXAHEDRON" ); break;
         case SMDSEntity_Penta:
         case SMDSEntity_Quad_Penta:
+        case SMDSEntity_BiQuad_Penta:
           gtype = SMESHGUI_ElemInfo::tr( "PRISM" ); break;
         case SMDSEntity_Hexagonal_Prism:
           gtype = SMESHGUI_ElemInfo::tr( "HEX_PRISM" ); break;
@@ -2942,6 +2950,8 @@ SMESHGUI_MeshInfoDlg::SMESHGUI_MeshInfoDlg( QWidget* parent, int page )
   connect( myElemInfo,  SIGNAL( itemInfo( int )),     this, SLOT( showItemInfo( int )));
   connect( myElemInfo,  SIGNAL( itemInfo( QString )), this, SLOT( showItemInfo( QString )));
 
+  myIDPreviewCheck->setChecked( SMESHGUI::resourceMgr()->booleanValue( "SMESH", id_preview_resource, false ));
+
   updateSelection();
 }
 
@@ -3189,6 +3199,7 @@ void SMESHGUI_MeshInfoDlg::idChanged()
 void SMESHGUI_MeshInfoDlg::idPreviewChange( bool isOn )
 {
   myIDPreview->SetPointsLabeled( isOn && !myID->text().simplified().isEmpty() );
+  SMESHGUI::resourceMgr()->setValue("SMESH", id_preview_resource, isOn );
   if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow() )
     aViewWindow->Repaint();
 }
index 4bb587ef74087d5cb74f22286edebcab28b7df44..ff20b1f8767d6f1b86bd0e517d784871e23e86b5 100644 (file)
@@ -70,7 +70,7 @@ SMESHGUI_MeshInfosBox::SMESHGUI_MeshInfosBox(const bool full, QWidget* theParent
   myNbHexa(0), myNbLinHexa(0), myNbQuadHexa(0), myNbBiQuadHexa(0),
   myNbTetra(0),myNbLinTetra(0),myNbQuadTetra(0),
   myNbPyra(0), myNbLinPyra(0), myNbQuadPyra(0),
-  myNbPrism(0),myNbLinPrism(0), myNbQuadPrism(0),
+  myNbPrism(0),myNbLinPrism(0), myNbQuadPrism(0), myNbBiQuadPrism(0),
   myNbVolum(0), myNbLinVolum(0), myNbQuadVolum(0), myNbBiQuadVolum(0),
   myNbHexaPrism(0),
   myNbPolyh(0)
@@ -309,6 +309,9 @@ SMESHGUI_MeshInfosBox::SMESHGUI_MeshInfosBox(const bool full, QWidget* theParent
     myNbQuadPrism = new QLabel( this );
     l->addWidget( myNbQuadPrism, row, 3 );
     // --
+    myNbBiQuadPrism = new QLabel( this );
+    l->addWidget( myNbBiQuadPrism, row, 4 );
+    // --
     row++;                       // increment row count
     // ... hexa prisms
     lab = new QLabel(COLONIZE(tr("SMESH_MESHINFO_HEXAPRISM")), this );
@@ -460,6 +463,7 @@ void SMESHGUI_MeshInfosBox::SetMeshInfo(const SMESH::long_array& theInfo)
                                                theInfo[SMDSEntity_TriQuad_Hexa] +
                                                theInfo[SMDSEntity_Penta] +
                                                theInfo[SMDSEntity_Quad_Penta] +
+                                               theInfo[SMDSEntity_BiQuad_Penta] +
                                                theInfo[SMDSEntity_Hexagonal_Prism] +
                                                theInfo[SMDSEntity_Polyhedra] ));
   myNbLinVolum   ->setText( QString("%1").arg( theInfo[SMDSEntity_Tetra] +
@@ -471,7 +475,8 @@ void SMESHGUI_MeshInfosBox::SetMeshInfo(const SMESH::long_array& theInfo)
                                                theInfo[SMDSEntity_Quad_Pyramid] +
                                                theInfo[SMDSEntity_Quad_Hexa] +
                                                theInfo[SMDSEntity_Quad_Penta] ));
-  myNbBiQuadVolum->setText( QString("%1").arg( theInfo[SMDSEntity_TriQuad_Hexa] ));
+  myNbBiQuadVolum->setText( QString("%1").arg( theInfo[SMDSEntity_TriQuad_Hexa] +
+                                               theInfo[SMDSEntity_BiQuad_Penta] ));
 
   if ( myFull )
   {
@@ -514,9 +519,11 @@ void SMESHGUI_MeshInfosBox::SetMeshInfo(const SMESH::long_array& theInfo)
     myNbQuadPyra ->setText( QString("%1").arg( theInfo[SMDSEntity_Quad_Pyramid] ));
     // prisms
     myNbPrism    ->setText( QString("%1").arg( theInfo[SMDSEntity_Penta] +
-                                               theInfo[SMDSEntity_Quad_Penta] ));
-    myNbLinPrism ->setText( QString("%1").arg( theInfo[SMDSEntity_Penta] ));
-    myNbQuadPrism->setText( QString("%1").arg( theInfo[SMDSEntity_Quad_Penta] ));
+                                               theInfo[SMDSEntity_Quad_Penta] +
+                                                                                          theInfo[SMDSEntity_BiQuad_Penta] ));
+    myNbLinPrism   ->setText( QString("%1").arg( theInfo[SMDSEntity_Penta] ));
+    myNbQuadPrism  ->setText( QString("%1").arg( theInfo[SMDSEntity_Quad_Penta] ));
+    myNbBiQuadPrism->setText( QString("%1").arg( theInfo[SMDSEntity_BiQuad_Penta] ));
     // octahedra
     myNbHexaPrism->setText( QString("%1").arg( theInfo[ SMDSEntity_Hexagonal_Prism ]));
     // polyedres
index c6ecbb3cfb5ecdedd78ea83d94f4f5813714a905..5671cf1d5852ec738d75fb7d3906df862308aab6 100644 (file)
@@ -84,6 +84,7 @@ private:
   QLabel* myNbPrism;
   QLabel* myNbLinPrism;
   QLabel* myNbQuadPrism;
+  QLabel* myNbBiQuadPrism;
   QLabel* myNbVolum;
   QLabel* myNbLinVolum;
   QLabel* myNbQuadVolum;
index f31874bb0be88e298906d82c13ece5201a2dbc36..1b50b43d1a9db1ff8fbb51ac44f6dd007537e4ff 100755 (executable)
@@ -435,7 +435,7 @@ void SMESHGUI_MultiEditDlg::onOk()
 
 //=======================================================================
 // name    : SMESHGUI_MultiEditDlg::getIds
-// Purpose : Retrive identifiers from list box or the whole object
+// Purpose : Retrieve identifiers from list box or the whole object
 //=======================================================================
 
 SMESH::long_array_var SMESHGUI_MultiEditDlg::getIds(SMESH::SMESH_IDSource_var& obj)
@@ -974,18 +974,18 @@ void SMESHGUI_MultiEditDlg::setSelectionMode()
   }
 
   if (entityType()) {
-    if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
-      aViewWindow->SetSelectionMode(VolumeSelection);
     SMESH::SetFilter(new SMESHGUI_VolumesFilter());
-  } else {
     if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
-      aViewWindow->SetSelectionMode(FaceSelection);
+      aViewWindow->SetSelectionMode(VolumeSelection); // here myActor set to a filter
+  } else {
     if (myFilterType == SMESH::TriaFilter)
       SMESH::SetFilter(new SMESHGUI_TriangleFilter());
     else if (myFilterType == SMESH::QuadFilter)
       SMESH::SetFilter(new SMESHGUI_QuadrangleFilter());
     else
       SMESH::SetFilter(new SMESHGUI_FacesFilter());
+    if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
+      aViewWindow->SetSelectionMode(FaceSelection); // here myActor set to a filter
   }
 }
 
index 89f53472bd9664f4c447f7c5067ce547a26742a9..63c9885cd83a7c11483237bfa6da063974e17ccc 100644 (file)
@@ -146,9 +146,10 @@ namespace SMESHOp {
     OpQuadraticTetrahedron   = 4105,   // MENU MODIFICATION - ADD - QUADRATIC TETRAHEDRON
     OpQuadraticPyramid       = 4106,   // MENU MODIFICATION - ADD - QUADRATIC PYRAMID
     OpQuadraticPentahedron   = 4107,   // MENU MODIFICATION - ADD - QUADRATIC PENTAHEDRON
-    OpQuadraticHexahedron    = 4108,   // MENU MODIFICATION - ADD - QUADRATIC HEXAHEDRON
-    OpTriQuadraticHexahedron = 4109,   // MENU MODIFICATION - ADD - TRIQUADRATIC HEXAHEDRON
-    OpQuadraticPolygon       = 4110,   // MENU MODIFICATION - ADD - QUADRATIC POLYGON
+    OpBiQuadraticPentahedron = 4108,   // MENU MODIFICATION - ADD - BIQUADRATIC PENTAHEDRON
+    OpQuadraticHexahedron    = 4110,   // MENU MODIFICATION - ADD - QUADRATIC HEXAHEDRON
+    OpTriQuadraticHexahedron = 4111,   // MENU MODIFICATION - ADD - TRIQUADRATIC HEXAHEDRON
+    OpQuadraticPolygon       = 4112,   // MENU MODIFICATION - ADD - QUADRATIC POLYGON
     OpRemoveNodes            = 4200,   // MENU MODIFICATION - REMOVE - NODE
     OpRemoveElements         = 4201,   // MENU MODIFICATION - REMOVE - ELEMENTS
     OpRemoveOrphanNodes      = 4202,   // MENU MODIFICATION - REMOVE - ORPHAN NODES
index 22e71be8a9b130e23d45df1d6e26a3ab933687ee..21f74593fbde626c20cdcba8a1061971d4209417 100644 (file)
@@ -280,7 +280,7 @@ namespace SMESH
   void ModifiedMesh (_PTR(SObject) theSObject, bool theIsNotModif, bool isEmptyMesh)
   {
     _PTR(Study) aStudy = GetActiveStudyDocument();
-    if (aStudy->GetProperties()->IsLocked())
+    if ( !aStudy || aStudy->GetProperties()->IsLocked() )
       return;
 
     _PTR(StudyBuilder) aBuilder = aStudy->NewBuilder();
index 9531e409fada3f9ad40e3e40d09df9c7ae7453da..3ccd58cba73e98357af4ec4d8df27596b5d259c6 100644 (file)
             <source>ICON_DLG_QUADRATIC_PENTAHEDRON</source>
             <translation>mesh_quad_pentahedron.png</translation>
         </message>
+        <message>
+            <source>ICON_DLG_BIQUADRATIC_PENTAHEDRON</source>
+            <translation>mesh_quad_pentahedron.png</translation>
+        </message>
         <message>
             <source>ICON_DLG_QUADRATIC_PYRAMID</source>
             <translation>mesh_quad_pyramid.png</translation>
index 2a0601830e89c7583f3eff093d7cb9f815b95811..31d955416735b0efdf9d5ae2b99be3016364ef52 100644 (file)
         <source>CGNS_FILES_FILTER</source>
         <translation>CGNS files</translation>
     </message>
+    <message>
+        <source>CGNS_EXPORT_ELEMS_BY_TYPE</source>
+        <translation>Group elements by type</translation>
+    </message>
     <message>
         <source>GMF_ASCII_FILES_FILTER</source>
         <translation>GMF ASCII files</translation>
         <source>MEN_QUADRATIC_PENTAHEDRON</source>
         <translation>Quadratic Pentahedron</translation>
     </message>
+    <message>
+        <source>MEN_BIQUADRATIC_PENTAHEDRON</source>
+        <translation>BiQuadratic Pentahedron</translation>
+    </message>
     <message>
         <source>MEN_QUADRATIC_PYRAMID</source>
         <translation>Quadratic Pyramid</translation>
@@ -1366,6 +1374,10 @@ Please enter correct values and try again</translation>
         <source>SMESH_ADD_QUADRATIC_PENTAHEDRON_TITLE</source>
         <translation>Add Quadratic Pentahedron</translation>
     </message>
+    <message>
+        <source>SMESH_ADD_BIQUADRATIC_PENTAHEDRON_TITLE</source>
+        <translation>Add BiQuadratic Pentahedron</translation>
+    </message>
     <message>
         <source>SMESH_ADD_QUADRATIC_PYRAMID_TITLE</source>
         <translation>Add Quadratic Pyramid</translation>
@@ -2526,10 +2538,18 @@ Check algorithm documentation for supported geometry</translation>
         <source>SMESH_QUADRATIC_PENTAHEDRON</source>
         <translation>Quadratic Pentahedron</translation>
     </message>
+    <message>
+        <source>SMESH_BIQUADRATIC_PENTAHEDRON</source>
+        <translation>BiQuadratic Pentahedron</translation>
+    </message>
     <message>
         <source>SMESH_QUADRATIC_PENTAHEDRONS</source>
         <translation>Quadratic Pentahedrons</translation>
     </message>
+    <message>
+        <source>SMESH_BIQUADRATIC_PENTAHEDRONS</source>
+        <translation>BiQuadratic Pentahedrons</translation>
+    </message>
     <message>
         <source>SMESH_QUADRATIC_PYRAMID</source>
         <translation>Quadratic Pyramid</translation>
@@ -3382,6 +3402,10 @@ Use Display Entity menu command to show them.
         <source>STB_QUADRATIC_PENTAHEDRON</source>
         <translation>Quadratic Pentahedron</translation>
     </message>
+    <message>
+        <source>STB_BIQUADRATIC_PENTAHEDRON</source>
+        <translation>BiQuadratic Pentahedron</translation>
+    </message>
     <message>
         <source>STB_QUADRATIC_PYRAMID</source>
         <translation>Quadratic Pyramid</translation>
@@ -4058,6 +4082,10 @@ Use Display Entity menu command to show them.
         <source>TOP_QUADRATIC_PENTAHEDRON</source>
         <translation>Quadratic Pentahedron</translation>
     </message>
+    <message>
+        <source>TOP_BIQUADRATIC_PENTAHEDRON</source>
+        <translation>BiQuadratic Pentahedron</translation>
+    </message>
     <message>
         <source>TOP_QUADRATIC_PYRAMID</source>
         <translation>Quadratic Pyramid</translation>
@@ -4895,6 +4923,10 @@ Please, create VTK viewer and try again</translation>
         <source>SMESH_ADD_QUADRATIC_PENTAHEDRON</source>
         <translation>Add Quadratic Pentahedron</translation>
     </message>
+    <message>
+        <source>SMESH_ADD_BIQUADRATIC_PENTAHEDRON</source>
+        <translation>Add BiQuadratic Pentahedron</translation>
+    </message>
     <message>
         <source>SMESH_ADD_QUADRATIC_PYRAMID</source>
         <translation>Add Quadratic Pyramid</translation>
@@ -6025,18 +6057,22 @@ Please enter correct value and try again</translation>
     </message>
     <message>
         <source>ENTITY_TYPE_21</source>
-        <translation>OCTA12</translation>
+        <translation>PENTA18</translation>
     </message>
     <message>
         <source>ENTITY_TYPE_22</source>
-        <translation>POLYEDRE</translation>
+        <translation>OCTA12</translation>
     </message>
     <message>
         <source>ENTITY_TYPE_23</source>
-        <translation>QPOLYEDRE</translation>
+        <translation>POLYEDRE</translation>
     </message>
     <message>
         <source>ENTITY_TYPE_24</source>
+        <translation>QPOLYEDRE</translation>
+    </message>
+    <message>
+        <source>ENTITY_TYPE_25</source>
         <translation>BALL</translation>
     </message>
     <message>
@@ -6996,6 +7032,14 @@ It is impossible to read point coordinates from file</translation>
         <source>SMESH_CREATE_GROUP_FROM_GEOM</source>
         <translation>Create Groups from Geometry</translation>
     </message>
+    <message>
+        <source>ELEMENTS</source>
+        <translation>Elements</translation>
+    </message>
+    <message>
+        <source>ELEMENTS_TOOLTIP</source>
+        <translation>No 0D elements</translation>
+    </message>
 </context>
 <context>
     <name>SMESHGUI_MeshOrderDlg</name>
index 032411ca789cf23b2d482ffef36fc8b8c3b7c975..2f5882e9983e92ed8e262014850e32c80b836b2b 100755 (executable)
         <source>CGNS_FILES_FILTER</source>
         <translation>Fichiers CGNS</translation>
     </message>
+    <message>
+        <source>CGNS_EXPORT_ELEMS_BY_TYPE</source>
+        <translation>Groupe les éléments par type</translation>
+    </message>
     <message>
         <source>GMF_ASCII_FILES_FILTER</source>
         <translation>Fichiers GMF ASCII</translation>
         <source>MEN_DEL_GROUP</source>
         <translation>Supprimer les groupes et leur contenu</translation>
     </message>
+    <message>
+        <source>MEN_ADD_TO_GROUP</source>
+        <translation>Ajoute dans le groupe</translation>
+    </message>
+    <message>
+        <source>MEN_REMOVE_FROM_GROUP</source>
+        <translation>Supprime du groupe</translation>
+    </message>
+    <message>
+        <source>STB_ADD_TO_GROUP</source>
+        <translation>Ajoute dans le groupe les éléments sélectionnés</translation>
+    </message>
+    <message>
+        <source>STB_REMOVE_FROM_GROUP</source>
+        <translation>Supprime du groupe les éléments sélectionnés</translation>
+    </message>
     <message>
         <source>MEN_FACE_ORIENTATION</source>
         <translation>Orientation des faces</translation>
         <source>MEN_QUADRATIC_PENTAHEDRON</source>
         <translation>Pentaèdre quadratique</translation>
     </message>
+    <message>
+        <source>MEN_BIQUADRATIC_PENTAHEDRON</source>
+        <translation>Pentaèdre biquadratique</translation>
+    </message>
     <message>
         <source>MEN_QUADRATIC_PYRAMID</source>
         <translation>Pyramide quadratique</translation>
@@ -1350,6 +1374,10 @@ Merci de les corriger, puis essayez de nouveau</translation>
         <source>SMESH_ADD_QUADRATIC_PENTAHEDRON_TITLE</source>
         <translation>Ajouter un pentaèdre quadratique</translation>
     </message>
+    <message>
+        <source>SMESH_ADD_BIQUADRATIC_PENTAHEDRON_TITLE</source>
+        <translation>Ajouter un pentaèdre biquadratique</translation>
+    </message>
     <message>
         <source>SMESH_ADD_QUADRATIC_PYRAMID_TITLE</source>
         <translation>Ajouter une pyramide quadratique</translation>
@@ -2510,10 +2538,18 @@ Référez-vous à la documentation sur l&apos;algorithme et la géométrie suppo
         <source>SMESH_QUADRATIC_PENTAHEDRON</source>
         <translation>Pentaèdre quadratique</translation>
     </message>
+    <message>
+        <source>SMESH_BIQUADRATIC_PENTAHEDRON</source>
+        <translation>Pentaèdre biquadratique</translation>
+    </message>
     <message>
         <source>SMESH_QUADRATIC_PENTAHEDRONS</source>
         <translation>Pentaèdres quadratiques</translation>
     </message>
+    <message>
+        <source>SMESH_BIQUADRATIC_PENTAHEDRONS</source>
+        <translation>Pentaèdres biquadratiques</translation>
+    </message>
     <message>
         <source>SMESH_QUADRATIC_PYRAMID</source>
         <translation>Pyramide quadratique</translation>
@@ -3367,6 +3403,10 @@ Utilisez le menu &quot;Visualiser une entité&quot; pour les afficher.
         <source>STB_QUADRATIC_PENTAHEDRON</source>
         <translation>Pentaèdre quadratique</translation>
     </message>
+    <message>
+        <source>STB_BIQUADRATIC_PENTAHEDRON</source>
+        <translation>Pentaèdre biquadratique</translation>
+    </message>
     <message>
         <source>STB_QUADRATIC_PYRAMID</source>
         <translation>Pyramide quadratique</translation>
@@ -4043,6 +4083,10 @@ Utilisez le menu &quot;Visualiser une entité&quot; pour les afficher.
         <source>TOP_QUADRATIC_PENTAHEDRON</source>
         <translation>Pentaèdre quadratique</translation>
     </message>
+    <message>
+        <source>TOP_BIQUADRATIC_PENTAHEDRON</source>
+        <translation>Pentaèdre biquadratique</translation>
+    </message>
     <message>
         <source>TOP_QUADRATIC_PYRAMID</source>
         <translation>Pyramide quadratique</translation>
@@ -4880,6 +4924,10 @@ Ouvrez une fenêtre VTK et essayez de nouveau</translation>
         <source>SMESH_ADD_QUADRATIC_PENTAHEDRON</source>
         <translation>Ajouter un pentaèdre quadratique</translation>
     </message>
+    <message>
+        <source>SMESH_ADD_BIQUADRATIC_PENTAHEDRON</source>
+        <translation>Ajouter un pentaèdre biquadratique</translation>
+    </message>
     <message>
         <source>SMESH_ADD_QUADRATIC_PYRAMID</source>
         <translation>Ajouter une pyramide quadratique</translation>
@@ -5309,6 +5357,10 @@ Choisissez un groupe et essayez de nouveau</translation>
         <source>SEPARATE_CORNERS_AND_MEDIUM</source>
         <translation>Pas de fusion du coin et des noeuds moyens des cellules quadratiques</translation>
     </message>
+    <message>
+        <source>AVOID_MAKING_HOLES</source>
+        <translation>Evite de créer des trous</translation>
+    </message>
     <message>
         <source>KEEP_NODES</source>
         <translation>Les noeuds à conserver pendant la fusion</translation>
@@ -6008,18 +6060,22 @@ Entrez une valeur correcte et essayez de nouveau</translation>
     </message>
     <message>
         <source>ENTITY_TYPE_21</source>
-        <translation>OCTA12</translation>
+        <translation>PENTA18</translation>
     </message>
     <message>
         <source>ENTITY_TYPE_22</source>
-        <translation>POLYEDRE</translation>
+        <translation>OCTA12</translation>
     </message>
     <message>
         <source>ENTITY_TYPE_23</source>
-        <translation>QPOLYEDRE</translation>
+        <translation>POLYEDRE</translation>
     </message>
     <message>
         <source>ENTITY_TYPE_24</source>
+        <translation>QPOLYEDRE</translation>
+    </message>
+    <message>
+        <source>ENTITY_TYPE_25</source>
         <translation>BALL</translation>
     </message>
     <message>
@@ -6979,6 +7035,14 @@ Il y a trop peu de points dans le fichier </translation>
         <source>SMESH_CREATE_GROUP_FROM_GEOM</source>
         <translation>Créer des groupes à partir de la géométrie</translation>
     </message>
+    <message>
+        <source>ELEMENTS</source>
+        <translation>Eléments</translation>
+    </message>
+    <message>
+        <source>ELEMENTS_TOOLTIP</source>
+        <translation>Pas d'éléments 0D</translation>
+    </message>
 </context>
 <context>
     <name>SMESHGUI_MeshOrderDlg</name>
@@ -7409,6 +7473,10 @@ en raison de leurs types incompatibles:
         <source>ELEM_MODE</source>
         <translation>Elément</translation>
     </message>
+    <message>
+        <source>SHOW_IDS</source>
+        <translation>Montre les IDs</translation>
+    </message>
     <message>
         <source>BUT_DUMP_MESH</source>
         <translation>&amp;Dump</translation>
index d18673c16e21e2e48cc904f721b3e72710fbe496..77c6734106723236f063334737afec997108258e 100644 (file)
       <source>CGNS_FILES_FILTER</source>
       <translation>CGNS ファイル</translation>
     </message>
+    <message>
+      <source>CGNS_EXPORT_ELEMS_BY_TYPE</source>
+      <translation>タイプで要素をグループ化</translation>
+    </message>
     <message>
       <source>GMF_ASCII_FILES_FILTER</source>
       <translation>GMFアスキーファイル</translation>
       <source>MEN_DEL_GROUP</source>
       <translation>グループとその内容を削除します。</translation>
     </message>
+    <message>
+      <source>MEN_ADD_TO_GROUP</source>
+      <translation>グループに追加</translation>
+    </message>
+    <message>
+      <source>MEN_REMOVE_FROM_GROUP</source>
+      <translation>グループから削除</translation>
+    </message>
+    <message>
+      <source>STB_ADD_TO_GROUP</source>
+      <translation>選択要素をグループに追加</translation>
+    </message>
+    <message>
+      <source>STB_REMOVE_FROM_GROUP</source>
+      <translation>選択要素をグループから削除</translation>
+    </message>
     <message>
       <source>MEN_FACE_ORIENTATION</source>
       <translation>フェースの向き</translation>
       <source>MEN_QUADRATIC_PENTAHEDRON</source>
       <translation>二次ウェッジ</translation>
     </message>
+    <message>
+      <source>MEN_BIQUADRATIC_PENTAHEDRON</source>
+      <translation>4次五面体</translation>
+    </message>
     <message>
       <source>MEN_QUADRATIC_PYRAMID</source>
       <translation>四角錐</translation>
       <source>SMESH_ADD_QUADRATIC_PENTAHEDRON_TITLE</source>
       <translation>二次くさびを追加します。</translation>
     </message>
+    <message>
+      <source>SMESH_ADD_BIQUADRATIC_PENTAHEDRON_TITLE</source>
+      <translation>4次五面体の追加</translation>
+    </message>
     <message>
       <source>SMESH_ADD_QUADRATIC_PYRAMID_TITLE</source>
       <translation>四角錐を追加します。</translation>
       <source>SMESH_QUADRATIC_PENTAHEDRON</source>
       <translation>二次ウェッジ</translation>
     </message>
+    <message>
+      <source>SMESH_BIQUADRATIC_PENTAHEDRON</source>
+      <translation>4次五面体</translation>
+    </message>
     <message>
       <source>SMESH_QUADRATIC_PENTAHEDRONS</source>
       <translation>二次ウェッジ</translation>
     </message>
+    <message>
+      <source>SMESH_BIQUADRATIC_PENTAHEDRONS</source>
+      <translation>4次五面体</translation>
+    </message>
     <message>
       <source>SMESH_QUADRATIC_PYRAMID</source>
       <translation>四角錐</translation>
       <source>STB_QUADRATIC_PENTAHEDRON</source>
       <translation>二次ウェッジ</translation>
     </message>
+    <message>
+      <source>STB_BIQUADRATIC_PENTAHEDRON</source>
+      <translation>4次五面体</translation>
+    </message>
     <message>
       <source>STB_QUADRATIC_PYRAMID</source>
       <translation>四角錐</translation>
       <source>TOP_QUADRATIC_PENTAHEDRON</source>
       <translation>二次ウェッジ</translation>
     </message>
+    <message>
+      <source>TOP_BIQUADRATIC_PENTAHEDRON</source>
+      <translation>4次五面体</translation>
+    </message>
     <message>
       <source>TOP_QUADRATIC_PYRAMID</source>
       <translation>四角錐</translation>
       <source>SMESH_ADD_QUADRATIC_PENTAHEDRON</source>
       <translation>二次くさびを追加します。</translation>
     </message>
+    <message>
+      <source>SMESH_ADD_BIQUADRATIC_PENTAHEDRON</source>
+      <translation>4次五面体の追加</translation>
+    </message>
     <message>
       <source>SMESH_ADD_QUADRATIC_PYRAMID</source>
       <translation>二次ピラミッドの追加</translation>
       <source>SEPARATE_CORNERS_AND_MEDIUM</source>
       <translation>2次セルのコーナ節点と中間節点をマージできません</translation>
     </message>
+    <message>
+      <source>AVOID_MAKING_HOLES</source>
+      <translation>穴作成の回避</translation>
+    </message>
     <message>
       <source>KEEP_NODES</source>
       <translation>維持節点</translation>
       <source>ENTITY_TYPE_24</source>
       <translation>ボール</translation>
     </message>
+    <message>
+      <source>ENTITY_TYPE_25</source>
+      <translation>ボール</translation>
+    </message>
     <message>
       <source>GEOM_TYPE</source>
       <translation>ジオメトリの種類</translation>
       <source>SMESH_CREATE_GROUP_FROM_GEOM</source>
       <translation>ジオメトリからグループを作成</translation>
     </message>
+    <message>
+      <source>ELEMENTS</source>
+      <translation>要素</translation>
+    </message>
+    <message>
+      <source>ELEMENTS_TOOLTIP</source>
+      <translation>0D要素がない</translation>
+    </message>
   </context>
   <context>
     <name>SMESHGUI_MeshOrderDlg</name>
       <source>ELEM_MODE</source>
       <translation>要素</translation>
     </message>
+    <message>
+      <source>SHOW_IDS</source>
+      <translation>IDの表示</translation>
+    </message>
     <message>
       <source>BUT_DUMP_MESH</source>
       <translation>書き出し(&amp;D)</translation>
index 3641d913cdd06639fd7a5cdc3ccbc18b6ce1bc8c..c84715eed262da158df4cb9103f7668cfc0a999f 100644 (file)
@@ -67,6 +67,7 @@ SET(SMESHUtils_HEADERS
   SMESH_MeshAlgos.hxx
   SMESH_MAT2d.hxx
   SMESH_ControlPnt.hxx
+  SMESH_Delaunay.hxx
 )
 
 # --- sources ---
@@ -84,6 +85,7 @@ SET(SMESHUtils_SOURCES
   SMESH_FreeBorders.cxx
   SMESH_ControlPnt.cxx
   SMESH_DeMerge.cxx
+  SMESH_Delaunay.cxx
   )
 
 # --- rules ---
diff --git a/src/SMESHUtils/SMESH_Delaunay.cxx b/src/SMESHUtils/SMESH_Delaunay.cxx
new file mode 100644 (file)
index 0000000..2a2809c
--- /dev/null
@@ -0,0 +1,374 @@
+// Copyright (C) 2007-2016  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// Copyright (C) 2003-2007  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, or (at your option) any later version.
+//
+// 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      : SMESH_Delaunay.cxx
+// Created   : Wed Apr 19 15:41:15 2017
+// Author    : Edward AGAPOV (eap)
+
+#include "SMESH_Delaunay.hxx"
+
+#include "SMESH_Comment.hxx"
+#include "SMESH_File.hxx"
+#include "SMESH_MeshAlgos.hxx"
+
+#include <BRepAdaptor_Surface.hxx>
+#include <BRepMesh_Delaun.hxx>
+
+//================================================================================
+/*!
+ * \brief Construct a Delaunay triangulation of given boundary nodes
+ *  \param [in] boundaryNodes - vector of nodes of a wire
+ *  \param [in] face - the face
+ *  \param [in] faceID - the face ID
+ *  \param [in] nbNodesToVisit - nb of non-marked nodes on the face
+ */
+//================================================================================
+
+SMESH_Delaunay::SMESH_Delaunay(const std::vector< const UVPtStructVec* > & boundaryNodes,
+                               const TopoDS_Face&                          face,
+                               const int                                   faceID)
+  : _face( face ), _faceID( faceID ), _scale( 1., 1. )
+{
+  // compute _scale
+  BRepAdaptor_Surface surf( face );
+  if ( surf.GetType() != GeomAbs_Plane )
+  {
+    const int nbDiv = 100;
+    const double uRange = surf.LastUParameter() - surf.FirstUParameter();
+    const double vRange = surf.LastVParameter() - surf.FirstVParameter();
+    const double dU = uRange / nbDiv;
+    const double dV = vRange / nbDiv;
+    double u = surf.FirstUParameter(), v = surf.FirstVParameter();
+    gp_Pnt p0U = surf.Value( u, v ), p0V = p0U;
+    double lenU = 0, lenV = 0;
+    for ( ; u < surf.LastUParameter(); u += dU, v += dV )
+    {
+      gp_Pnt p1U = surf.Value( u, surf.FirstVParameter() );
+      lenU += p1U.Distance( p0U );
+      p0U = p1U;
+      gp_Pnt p1V = surf.Value( surf.FirstUParameter(), v );
+      lenV += p1V.Distance( p0V );
+      p0V = p1V;
+    }
+    _scale.SetCoord( lenU / uRange, lenV / vRange );
+  }
+
+  // count boundary points
+  int iP = 1, nbP = 0;
+  for ( size_t iW = 0; iW < boundaryNodes.size(); ++iW ) // loop on wires
+  {
+    nbP += boundaryNodes[iW]->size();
+    if ( boundaryNodes[iW]->front().node == boundaryNodes[iW]->back().node )
+      --nbP; // 1st and last points coincide
+  }
+  _bndNodes.resize( nbP );
+
+  // fill boundary points
+  BRepMesh::Array1OfVertexOfDelaun bndVert( 1, 1 + nbP );
+  BRepMesh_Vertex v( 0, 0, BRepMesh_Frontier );
+  for ( size_t iW = 0; iW < boundaryNodes.size(); ++iW )
+  {
+    const UVPtStructVec& bndPnt = *boundaryNodes[iW];
+    int i = 0, nb = bndPnt.size();
+    if ( bndPnt[0].node == bndPnt.back().node )
+      --nb;
+    for ( ; i < nb;  ++i, ++iP )
+    {
+      _bndNodes[ iP-1 ] = bndPnt[i].node;
+      bndPnt[i].node->setIsMarked( true );
+
+      v.ChangeCoord() = bndPnt[i].UV().Multiplied( _scale );
+      bndVert( iP )   = v;
+    }
+  }
+
+  // triangulate the srcFace in 2D
+  BRepMesh_Delaun Delaunay( bndVert );
+  _triaDS = Delaunay.Result();
+}
+
+//================================================================================
+/*!
+ * \brief Prepare to the exploration of nodes
+ */
+//================================================================================
+
+void SMESH_Delaunay::InitTraversal(const int nbNodesToVisit)
+{
+  _nbNodesToVisit = (size_t) nbNodesToVisit;
+  _nbVisitedNodes = _iBndNode = 0;
+  _noTriQueue.clear();
+}
+
+//================================================================================
+/*!
+ * \brief Return a node with its Barycentric Coordinates within the triangle
+ *        defined by its node indices (zero based)
+ *  \param [out] bc - Barycentric Coordinates of the returned node
+ *  \param [out] triaNodes - indices of triangle nodes
+ *  \return const SMDS_MeshNode* - the next node or NULL
+ */
+//================================================================================
+
+const SMDS_MeshNode* SMESH_Delaunay::NextNode( double bc[3], int triaNodes[3] )
+{
+  while ( _nbVisitedNodes < _nbNodesToVisit )
+  {
+    while ( !_noTriQueue.empty() )
+    {
+      const SMDS_MeshNode*     node = _noTriQueue.front().first;
+      const BRepMesh_Triangle* tria = _noTriQueue.front().second;
+      _noTriQueue.pop_front();
+      if ( node->isMarked() )
+        continue;
+      ++_nbVisitedNodes;
+      node->setIsMarked( true );
+
+      // find a Delaunay triangle containing the src node
+      gp_XY uv = getNodeUV( _face, node );
+      tria = FindTriangle( uv, tria, bc, triaNodes );
+      if ( tria )
+      {
+        addCloseNodes( node, tria, _faceID, _noTriQueue );
+        return node;
+      }
+    }
+    for ( ; _iBndNode < _bndNodes.size() &&  _noTriQueue.empty();  ++_iBndNode )
+    {
+      if ( const BRepMesh_Triangle* tria = GetTriangleNear( _iBndNode ))
+        addCloseNodes( _bndNodes[ _iBndNode ], tria, _faceID, _noTriQueue );
+    }
+    if ( _noTriQueue.empty() )
+      break;
+  }
+
+  // if ( _nbVisitedNodes < _nbNodesToVisit )
+  //   _nbVisitedNodes = std::numeric_limits<int>::max();
+  return NULL;
+}
+
+//================================================================================
+/*!
+ * \brief Find a Delaunay triangle containing a given 2D point and return
+ *        barycentric coordinates within the found triangle
+ */
+//================================================================================
+
+const BRepMesh_Triangle* SMESH_Delaunay::FindTriangle( const gp_XY&             UV,
+                                                       const BRepMesh_Triangle* tria,
+                                                       double                   bc[3],
+                                                       int                      triaNodes[3] )
+{
+  int   nodeIDs[3];
+  gp_XY nodeUVs[3];
+  int   linkIDs[3];
+  Standard_Boolean ori[3];
+
+  gp_XY uv = UV.Multiplied( _scale );
+
+  while ( tria )
+  {
+    // check if the uv is in tria
+
+    _triaDS->ElementNodes( *tria, nodeIDs );
+    nodeUVs[0] = _triaDS->GetNode( nodeIDs[0] ).Coord();
+    nodeUVs[1] = _triaDS->GetNode( nodeIDs[1] ).Coord();
+    nodeUVs[2] = _triaDS->GetNode( nodeIDs[2] ).Coord();
+
+    SMESH_MeshAlgos::GetBarycentricCoords( uv,
+                                           nodeUVs[0], nodeUVs[1], nodeUVs[2],
+                                           bc[0], bc[1] );
+    if ( bc[0] >= 0 && bc[1] >= 0 && bc[0] + bc[1] <= 1 )
+    {
+      if ( _triaDS->GetNode( nodeIDs[0] ).Movability() != BRepMesh_Frontier ||
+           _triaDS->GetNode( nodeIDs[1] ).Movability() != BRepMesh_Frontier ||
+           _triaDS->GetNode( nodeIDs[2] ).Movability() != BRepMesh_Frontier )
+      {
+        return 0;
+      }
+      bc[2] = 1 - bc[0] - bc[1];
+      triaNodes[0] = nodeIDs[0] - 1;
+      triaNodes[1] = nodeIDs[1] - 1;
+      triaNodes[2] = nodeIDs[2] - 1;
+      return tria;
+    }
+
+    // look for a neighbor triangle, which is adjacent to a link intersected
+    // by a segment( triangle center -> uv )
+
+    gp_XY gc = ( nodeUVs[0] + nodeUVs[1] + nodeUVs[2] ) / 3.;
+    gp_XY seg = uv - gc;
+
+    tria->Edges( linkIDs, ori );
+    int triaID = _triaDS->IndexOf( *tria );
+    tria = 0;
+
+    for ( int i = 0; i < 3; ++i )
+    {
+      const BRepMesh_PairOfIndex & triIDs = _triaDS->ElementsConnectedTo( linkIDs[i] );
+      if ( triIDs.Extent() < 2 )
+        continue; // no neighbor triangle
+
+      // check if a link intersects gc2uv
+      const BRepMesh_Edge & link = _triaDS->GetLink( linkIDs[i] );
+      const BRepMesh_Vertex & n1 = _triaDS->GetNode( link.FirstNode() );
+      const BRepMesh_Vertex & n2 = _triaDS->GetNode( link.LastNode() );
+      gp_XY uv1 = n1.Coord();
+      gp_XY lin = n2.Coord() - uv1; // link direction
+
+      double crossSegLin = seg ^ lin;
+      if ( Abs( crossSegLin ) < std::numeric_limits<double>::min() )
+        continue; // parallel
+
+      double uSeg = ( uv1 - gc ) ^ lin / crossSegLin;
+      if ( 0. <= uSeg && uSeg <= 1. )
+      {
+        tria = & _triaDS->GetElement( triIDs.Index( 1 + ( triIDs.Index(1) == triaID )));
+        if ( tria->Movability() != BRepMesh_Deleted )
+          break;
+      }
+    }
+  }
+  return tria;
+}
+
+//================================================================================
+/*!
+ * \brief Return a triangle sharing a given boundary node
+ *  \param [in] iBndNode - index of the boundary node
+ *  \return const BRepMesh_Triangle* - a found triangle
+ */
+//================================================================================
+
+const BRepMesh_Triangle* SMESH_Delaunay::GetTriangleNear( int iBndNode )
+{
+  int nodeIDs[3];
+  int nbNbNodes = _bndNodes.size();
+  const BRepMesh::ListOfInteger & linkIds = _triaDS->LinksConnectedTo( iBndNode + 1 );
+  BRepMesh::ListOfInteger::const_iterator iLink = linkIds.cbegin();
+  for ( ; iLink != linkIds.cend(); ++iLink )
+  {
+    const BRepMesh_PairOfIndex & triaIds = _triaDS->ElementsConnectedTo( *iLink );
+    {
+      const BRepMesh_Triangle& tria = _triaDS->GetElement( triaIds.Index(1) );
+      if ( tria.Movability() != BRepMesh_Deleted )
+      {
+        _triaDS->ElementNodes( tria, nodeIDs );
+        if ( nodeIDs[0]-1 < nbNbNodes &&
+             nodeIDs[1]-1 < nbNbNodes &&
+             nodeIDs[2]-1 < nbNbNodes )
+          return &tria;
+      }
+    }
+    if ( triaIds.Extent() > 1 )
+    {
+      const BRepMesh_Triangle& tria = _triaDS->GetElement( triaIds.Index(2) );
+      if ( tria.Movability() != BRepMesh_Deleted )
+      {
+        _triaDS->ElementNodes( tria, nodeIDs );
+        if ( nodeIDs[0]-1 < nbNbNodes &&
+             nodeIDs[1]-1 < nbNbNodes &&
+             nodeIDs[2]-1 < nbNbNodes )
+          return &tria;
+      }
+    }
+  }
+  return 0;
+}
+
+//================================================================================
+/*!
+ * \brief Return UV of the i-th source boundary node (zero based)
+ */
+//================================================================================
+
+gp_XY SMESH_Delaunay::GetBndUV(const int iNode) const
+{
+  return _triaDS->GetNode( iNode+1 ).Coord();
+}
+
+//================================================================================
+/*!
+ * \brief Add non-marked nodes surrounding a given one to a queue
+ */
+//================================================================================
+
+void SMESH_Delaunay::addCloseNodes( const SMDS_MeshNode*     node,
+                                    const BRepMesh_Triangle* tria,
+                                    const int                faceID,
+                                    TNodeTriaList &          _noTriQueue )
+{
+  // find in-FACE nodes
+  SMDS_ElemIteratorPtr elems = node->GetInverseElementIterator(SMDSAbs_Face);
+  while ( elems->more() )
+  {
+    const SMDS_MeshElement* elem = elems->next();
+    if ( elem->getshapeId() == faceID )
+    {
+      for ( int i = 0, nb = elem->NbNodes(); i < nb; ++i )
+      {
+        const SMDS_MeshNode* n = elem->GetNode( i );
+        if ( !n->isMarked() /*&& n->getshapeId() == faceID*/ )
+          _noTriQueue.push_back( std::make_pair( n, tria ));
+      }
+    }
+  }
+}
+
+//================================================================================
+/*!
+ * \brief Write a python script that creates an equal mesh in Mesh module
+ */
+//================================================================================
+
+void SMESH_Delaunay::ToPython() const
+{
+  SMESH_Comment text;
+  text << "import salome, SMESH\n";
+  text << "salome.salome_init()\n";
+  text << "from salome.smesh import smeshBuilder\n";
+  text << "smesh = smeshBuilder.New(salome.myStudy)\n";
+  text << "mesh=smesh.Mesh()\n";
+  const char* endl = "\n";
+
+  for ( int i = 0; i < _triaDS->NbNodes(); ++i )
+  {
+    const BRepMesh_Vertex& v = _triaDS->GetNode( i+1 );
+    text << "mesh.AddNode( " << v.Coord().X() << ", " << v.Coord().Y() << ", 0 )" << endl;
+  }
+
+  int nodeIDs[3];
+  for ( int i = 0; i < _triaDS->NbElements(); ++i )
+  {
+    const BRepMesh_Triangle& t = _triaDS->GetElement( i+1 );
+    if ( t.Movability() == BRepMesh_Deleted )
+      continue;
+    _triaDS->ElementNodes( t, nodeIDs );
+    text << "mesh.AddFace([ " << nodeIDs[0] << ", " << nodeIDs[1] << ", " << nodeIDs[2] << " ])" << endl;
+  }
+
+  const char* fileName = "/tmp/Delaunay.py";
+  SMESH_File file( fileName, false );
+  file.remove();
+  file.openForWriting();
+  file.write( text.c_str(), text.size() );
+  cout << "execfile( '" << fileName << "')" << endl;
+}
diff --git a/src/SMESHUtils/SMESH_Delaunay.hxx b/src/SMESHUtils/SMESH_Delaunay.hxx
new file mode 100644 (file)
index 0000000..7170711
--- /dev/null
@@ -0,0 +1,115 @@
+// Copyright (C) 2007-2016  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// Copyright (C) 2003-2007  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, or (at your option) any later version.
+//
+// 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      : SMESH_Delaunay.hxx
+// Created   : Wed Apr 19 15:42:54 2017
+// Author    : Edward AGAPOV (eap)
+
+
+#ifndef __SMESH_Delaunay_HXX__
+#define __SMESH_Delaunay_HXX__
+
+#include "SMESH_TypeDefs.hxx"
+
+#include <BRepMesh_DataStructureOfDelaun.hxx>
+
+/*!
+ * \brief Create a Delaunay triangulation of nodes on a face boundary
+ *        and provide exploration of nodes shared by elements lying on
+ *        the face. For a returned node, also return a Delaunay triangle
+ *        the node lies in and its Barycentric Coordinates within the triangle.
+ *        Only non-marked nodes are visited. Boundary nodes given at the construction
+ *        are not returned.
+ *
+ *        For usage, this class needs to be subclassed to implement getNodeUV();
+ */
+class SMESHUtils_EXPORT SMESH_Delaunay
+{
+ public:
+
+  // construct a Delaunay triangulation of given boundary nodes
+  SMESH_Delaunay(const std::vector< const UVPtStructVec* > & boundaryNodes,
+                 const TopoDS_Face&                          face,
+                 const int                                   faceID);
+
+  virtual ~SMESH_Delaunay() {}
+
+  // prepare to the exploration of nodes
+  void InitTraversal(const int nbNodesToVisit = -1);
+
+  // return a node with its Barycentric Coordinates within the triangle
+  // defined by its node indices (zero based)
+  const SMDS_MeshNode* NextNode( double bc[3], int triaNodes[3] );
+
+  // return nb of nodes returned by NextNode()
+  int NbVisitedNodes() const { return _nbVisitedNodes; }
+
+
+  // find a triangle containing an UV, starting from a given triangle;
+  // return barycentric coordinates of the UV and the found triangle (indices are zero based).
+  const BRepMesh_Triangle* FindTriangle( const gp_XY&             uv,
+                                         const BRepMesh_Triangle* bmTria,
+                                         double                   bc[3],
+                                         int                      triaNodes[3]);
+
+  // return any Delaunay triangle neighboring a given boundary node (zero based)
+  const BRepMesh_Triangle* GetTriangleNear( int iBndNode );
+
+  // return source boundary nodes
+  const std::vector< const SMDS_MeshNode* >& GetBndNodes() const { return _bndNodes; }
+
+  // return UV of the i-th source boundary node (zero based)
+  gp_XY GetBndUV(const int iNode) const;
+
+  // return scale factor to convert real UV to/from UV used for Delauney meshing:
+  // delauney_UV = real_UV * scale
+  const gp_XY& GetScale() const { return _scale; }
+
+  void ToPython() const;
+
+  Handle(BRepMesh_DataStructureOfDelaun) GetDS() { return _triaDS; }
+
+ protected:
+
+  // container of a node and a triangle serving as a start while searching a
+  // triangle including the node UV
+  typedef std::list< std::pair< const SMDS_MeshNode*, const BRepMesh_Triangle* > > TNodeTriaList;
+
+  // return UV of a node on the face
+  virtual gp_XY getNodeUV( const TopoDS_Face& face, const SMDS_MeshNode* node ) const = 0;
+
+  // add non-marked nodes surrounding a given one to a queue
+  static void addCloseNodes( const SMDS_MeshNode*     node,
+                             const BRepMesh_Triangle* bmTria,
+                             const int                faceID,
+                             TNodeTriaList &          noTriQueue );
+
+  const TopoDS_Face&                     _face;
+  int                                    _faceID;
+  std::vector< const SMDS_MeshNode* >    _bndNodes;
+  gp_XY                                  _scale;
+  Handle(BRepMesh_DataStructureOfDelaun) _triaDS;
+  size_t                                 _nbNodesToVisit, _nbVisitedNodes, _iBndNode;
+  TNodeTriaList                          _noTriQueue;
+
+};
+
+#endif
index 1eae5f7818e23d205812d4330a7e8437c34349cb..8464e245fe197e6765f100a08498d730211522bb 100644 (file)
@@ -228,15 +228,15 @@ namespace // Utils used in SMESH_ElementSearcherImpl::FindElementsByPoint()
                       SMDSAbs_ElementType  elemType,
                       SMDS_ElemIteratorPtr theElemIt = SMDS_ElemIteratorPtr(),
                       double               tolerance = NodeRadius );
-    void getElementsNearPoint( const gp_Pnt& point, TIDSortedElemSet& foundElems );
-    void getElementsNearLine ( const gp_Ax1& line, TIDSortedElemSet& foundElems);
-    void getElementsInSphere ( const gp_XYZ& center,
-                               const double  radius, TIDSortedElemSet& foundElems);
-    size_t getSize() { return std::max( _size, _elements.size() ); }
-    virtual ~ElementBndBoxTree();
+    void prepare(); // !!!call it before calling the following methods!!!
+    void getElementsNearPoint( const gp_Pnt& point, vector<const SMDS_MeshElement*>& foundElems );
+    void getElementsNearLine ( const gp_Ax1& line,  vector<const SMDS_MeshElement*>& foundElems);
+    void getElementsInSphere ( const gp_XYZ&                    center,
+                               const double                     radius,
+                               vector<const SMDS_MeshElement*>& foundElems);
 
   protected:
-    ElementBndBoxTree():_size(0) {}
+    ElementBndBoxTree() {}
     SMESH_Octree* newChild() const { return new ElementBndBoxTree; }
     void          buildChildrenData();
     Bnd_B3d*      buildRootBox();
@@ -245,11 +245,25 @@ namespace // Utils used in SMESH_ElementSearcherImpl::FindElementsByPoint()
     struct ElementBox : public Bnd_B3d
     {
       const SMDS_MeshElement* _element;
-      int                     _refCount; // an ElementBox can be included in several tree branches
-      ElementBox(const SMDS_MeshElement* elem, double tolerance);
+      bool                    _isMarked;
+      void init(const SMDS_MeshElement* elem, double tolerance);
     };
     vector< ElementBox* > _elements;
-    size_t                _size;
+
+    typedef ObjectPool< ElementBox > TElementBoxPool;
+
+    //!< allocator of ElementBox's and SMESH_TreeLimit
+    struct LimitAndPool : public SMESH_TreeLimit
+    {
+      TElementBoxPool            _elBoPool;
+      std::vector< ElementBox* > _markedElems;
+      LimitAndPool():SMESH_TreeLimit( MaxLevel, /*minSize=*/0. ) {}
+    };
+    LimitAndPool* getLimitAndPool() const
+    {
+      SMESH_TreeLimit* limitAndPool = const_cast< SMESH_TreeLimit* >( myLimit );
+      return static_cast< LimitAndPool* >( limitAndPool );
+    }
   };
 
   //================================================================================
@@ -258,32 +272,27 @@ namespace // Utils used in SMESH_ElementSearcherImpl::FindElementsByPoint()
    */
   //================================================================================
 
-  ElementBndBoxTree::ElementBndBoxTree(const SMDS_Mesh& mesh, SMDSAbs_ElementType elemType, SMDS_ElemIteratorPtr theElemIt, double tolerance)
-    :SMESH_Octree( new SMESH_TreeLimit( MaxLevel, /*minSize=*/0. ))
+  ElementBndBoxTree::ElementBndBoxTree(const SMDS_Mesh&     mesh,
+                                       SMDSAbs_ElementType  elemType,
+                                       SMDS_ElemIteratorPtr theElemIt,
+                                       double               tolerance)
+    :SMESH_Octree( new LimitAndPool() )
   {
     int nbElems = mesh.GetMeshInfo().NbElements( elemType );
     _elements.reserve( nbElems );
 
+    TElementBoxPool& elBoPool = getLimitAndPool()->_elBoPool;
+
     SMDS_ElemIteratorPtr elemIt = theElemIt ? theElemIt : mesh.elementsIterator( elemType );
     while ( elemIt->more() )
-      _elements.push_back( new ElementBox( elemIt->next(),tolerance  ));
-
+    {
+      ElementBox* eb = elBoPool.getNew();
+      eb->init( elemIt->next(), tolerance );
+      _elements.push_back( eb );
+    }
     compute();
   }
 
-  //================================================================================
-  /*!
-   * \brief Destructor
-   */
-  //================================================================================
-
-  ElementBndBoxTree::~ElementBndBoxTree()
-  {
-    for ( size_t i = 0; i < _elements.size(); ++i )
-      if ( --_elements[i]->_refCount <= 0 )
-        delete _elements[i];
-  }
-
   //================================================================================
   /*!
    * \brief Return the maximal box
@@ -311,14 +320,10 @@ namespace // Utils used in SMESH_ElementSearcherImpl::FindElementsByPoint()
       for (int j = 0; j < 8; j++)
       {
         if ( !_elements[i]->IsOut( *myChildren[j]->getBox() ))
-        {
-          _elements[i]->_refCount++;
           ((ElementBndBoxTree*)myChildren[j])->_elements.push_back( _elements[i]);
-        }
       }
-      _elements[i]->_refCount--;
     }
-    _size = _elements.size();
+    //_size = _elements.size();
     SMESHUtils::FreeVector( _elements ); // = _elements.clear() + free memory
 
     for (int j = 0; j < 8; j++)
@@ -327,33 +332,61 @@ namespace // Utils used in SMESH_ElementSearcherImpl::FindElementsByPoint()
       if ((int) child->_elements.size() <= MaxNbElemsInLeaf )
         child->myIsLeaf = true;
 
-      if ( child->_elements.capacity() - child->_elements.size() > 1000 )
+      if ( child->isLeaf() && child->_elements.capacity() > child->_elements.size() )
         SMESHUtils::CompactVector( child->_elements );
     }
   }
 
+  //================================================================================
+  /*!
+   * \brief Un-mark all elements
+   */
+  //================================================================================
+
+  void ElementBndBoxTree::prepare()
+  {
+    // TElementBoxPool& elBoPool = getElementBoxPool();
+    // for ( size_t i = 0; i < elBoPool.nbElements(); ++i )
+    //   const_cast< ElementBox* >( elBoPool[ i ])->_isMarked = false;
+  }
+
   //================================================================================
   /*!
    * \brief Return elements which can include the point
    */
   //================================================================================
 
-  void ElementBndBoxTree::getElementsNearPoint( const gp_Pnt&     point,
-                                                TIDSortedElemSet& foundElems)
+  void ElementBndBoxTree::getElementsNearPoint( const gp_Pnt&                    point,
+                                                vector<const SMDS_MeshElement*>& foundElems)
   {
     if ( getBox()->IsOut( point.XYZ() ))
       return;
 
     if ( isLeaf() )
     {
+      LimitAndPool* pool = getLimitAndPool();
+
       for ( size_t i = 0; i < _elements.size(); ++i )
-        if ( !_elements[i]->IsOut( point.XYZ() ))
-          foundElems.insert( _elements[i]->_element );
+        if ( !_elements[i]->IsOut( point.XYZ() ) &&
+             !_elements[i]->_isMarked )
+        {
+          foundElems.push_back( _elements[i]->_element );
+          _elements[i]->_isMarked = true;
+          pool->_markedElems.push_back( _elements[i] );
+        }
     }
     else
     {
       for (int i = 0; i < 8; i++)
         ((ElementBndBoxTree*) myChildren[i])->getElementsNearPoint( point, foundElems );
+
+      if ( level() == 0 )
+      {
+        LimitAndPool* pool = getLimitAndPool();
+        for ( size_t i = 0; i < pool->_markedElems.size(); ++i )
+          pool->_markedElems[i]->_isMarked = false;
+        pool->_markedElems.clear();
+      }
     }
   }
 
@@ -363,22 +396,37 @@ namespace // Utils used in SMESH_ElementSearcherImpl::FindElementsByPoint()
    */
   //================================================================================
 
-  void ElementBndBoxTree::getElementsNearLine( const gp_Ax1&     line,
-                                               TIDSortedElemSet& foundElems)
+  void ElementBndBoxTree::getElementsNearLine( const gp_Ax1&                    line,
+                                               vector<const SMDS_MeshElement*>& foundElems)
   {
     if ( getBox()->IsOut( line ))
       return;
 
     if ( isLeaf() )
     {
+      LimitAndPool* pool = getLimitAndPool();
+
       for ( size_t i = 0; i < _elements.size(); ++i )
-        if ( !_elements[i]->IsOut( line ))
-          foundElems.insert( _elements[i]->_element );
+        if ( !_elements[i]->IsOut( line ) &&
+             !_elements[i]->_isMarked )
+        {
+          foundElems.push_back( _elements[i]->_element );
+          _elements[i]->_isMarked = true;
+          pool->_markedElems.push_back( _elements[i] );
+        }
     }
     else
     {
       for (int i = 0; i < 8; i++)
         ((ElementBndBoxTree*) myChildren[i])->getElementsNearLine( line, foundElems );
+
+      if ( level() == 0 )
+      {
+        LimitAndPool* pool = getLimitAndPool();
+        for ( size_t i = 0; i < pool->_markedElems.size(); ++i )
+          pool->_markedElems[i]->_isMarked = false;
+        pool->_markedElems.clear();
+      }
     }
   }
 
@@ -388,23 +436,38 @@ namespace // Utils used in SMESH_ElementSearcherImpl::FindElementsByPoint()
    */
   //================================================================================
 
-  void ElementBndBoxTree::getElementsInSphere ( const gp_XYZ&     center,
-                                                const double      radius,
-                                                TIDSortedElemSet& foundElems)
+  void ElementBndBoxTree::getElementsInSphere ( const gp_XYZ&                    center,
+                                                const double                     radius,
+                                                vector<const SMDS_MeshElement*>& foundElems)
   {
     if ( getBox()->IsOut( center, radius ))
       return;
 
     if ( isLeaf() )
     {
+      LimitAndPool* pool = getLimitAndPool();
+
       for ( size_t i = 0; i < _elements.size(); ++i )
-        if ( !_elements[i]->IsOut( center, radius ))
-          foundElems.insert( _elements[i]->_element );
+        if ( !_elements[i]->IsOut( center, radius ) &&
+             !_elements[i]->_isMarked )
+        {
+          foundElems.push_back( _elements[i]->_element );
+          _elements[i]->_isMarked = true;
+          pool->_markedElems.push_back( _elements[i] );
+        }
     }
     else
     {
       for (int i = 0; i < 8; i++)
         ((ElementBndBoxTree*) myChildren[i])->getElementsInSphere( center, radius, foundElems );
+
+      if ( level() == 0 )
+      {
+        LimitAndPool* pool = getLimitAndPool();
+        for ( size_t i = 0; i < pool->_markedElems.size(); ++i )
+          pool->_markedElems[i]->_isMarked = false;
+        pool->_markedElems.clear();
+      }
     }
   }
 
@@ -414,13 +477,13 @@ namespace // Utils used in SMESH_ElementSearcherImpl::FindElementsByPoint()
    */
   //================================================================================
 
-  ElementBndBoxTree::ElementBox::ElementBox(const SMDS_MeshElement* elem, double tolerance)
+  void ElementBndBoxTree::ElementBox::init(const SMDS_MeshElement* elem, double tolerance)
   {
     _element  = elem;
-    _refCount = 1;
+    _isMarked = false;
     SMDS_ElemIteratorPtr nIt = elem->nodesIterator();
     while ( nIt->more() )
-      Add( SMESH_TNodeXYZ( nIt->next() ));
+      Add( SMESH_NodeXYZ( nIt->next() ));
     Enlarge( tolerance );
   }
 
@@ -604,7 +667,7 @@ bool SMESH_ElementSearcherImpl::getIntersParamOnLine(const gp_Lin&           lin
     anExtCC.Init( lineCurve, edge.Value() );
     if ( anExtCC.NbExtrema() > 0 && anExtCC.LowerDistance() <= tol)
     {
-      Quantity_Parameter pl, pe;
+      Standard_Real pl, pe;
       anExtCC.LowerDistanceParameters( pl, pe );
       param += pl;
       if ( ++nbInts == 2 )
@@ -771,9 +834,13 @@ FindElementsByPoint(const gp_Pnt&                      point,
     {
       _ebbTree[_elementType] = new ElementBndBoxTree( *_mesh, type, _meshPartIt, tolerance );
     }
-    TIDSortedElemSet suspectElems;
+    else
+    {
+      _ebbTree[ type ]->prepare();
+    }
+    vector< const SMDS_MeshElement* > suspectElems;
     _ebbTree[ type ]->getElementsNearPoint( point, suspectElems );
-    TIDSortedElemSet::iterator elem = suspectElems.begin();
+    vector< const SMDS_MeshElement* >::iterator elem = suspectElems.begin();
     for ( ; elem != suspectElems.end(); ++elem )
       if ( !SMESH_MeshAlgos::IsOut( *elem, point, tolerance ))
         foundElements.push_back( *elem );
@@ -801,8 +868,10 @@ SMESH_ElementSearcherImpl::FindClosestTo( const gp_Pnt&       point,
     ElementBndBoxTree*& ebbTree = _ebbTree[ type ];
     if ( !ebbTree )
       ebbTree = new ElementBndBoxTree( *_mesh, type, _meshPartIt );
+    else
+      ebbTree->prepare();
 
-    TIDSortedElemSet suspectElems;
+    vector<const SMDS_MeshElement*> suspectElems;
     ebbTree->getElementsNearPoint( point, suspectElems );
 
     if ( suspectElems.empty() && ebbTree->maxSize() > 0 )
@@ -816,13 +885,14 @@ SMESH_ElementSearcherImpl::FindClosestTo( const gp_Pnt&       point,
         radius = ebbTree->maxSize() / pow( 2., getTreeHeight()) / 2;
       while ( suspectElems.empty() )
       {
+        ebbTree->prepare();
         ebbTree->getElementsInSphere( point.XYZ(), radius, suspectElems );
         radius *= 1.1;
       }
     }
     double minDist = std::numeric_limits<double>::max();
     multimap< double, const SMDS_MeshElement* > dist2face;
-    TIDSortedElemSet::iterator elem = suspectElems.begin();
+    vector<const SMDS_MeshElement*>::iterator elem = suspectElems.begin();
     for ( ; elem != suspectElems.end(); ++elem )
     {
       double dist = SMESH_MeshAlgos::GetDistance( *elem, point );
@@ -886,6 +956,8 @@ TopAbs_State SMESH_ElementSearcherImpl::GetPointState(const gp_Pnt& point)
   ElementBndBoxTree*& ebbTree = _ebbTree[ SMDSAbs_Face ];
   if ( !ebbTree )
     ebbTree = new ElementBndBoxTree( *_mesh, _elementType, _meshPartIt );
+  else
+    ebbTree->prepare();
 
   // Algo: analyse transition of a line starting at the point through mesh boundary;
   // try three lines parallel to axis of the coordinate system and perform rough
@@ -901,13 +973,14 @@ TopAbs_State SMESH_ElementSearcherImpl::GetPointState(const gp_Pnt& point)
     gp_Ax1 lineAxis( point, axisDir[axis]);
     gp_Lin line    ( lineAxis );
 
-    TIDSortedElemSet suspectFaces; // faces possibly intersecting the line
+    vector<const SMDS_MeshElement*> suspectFaces; // faces possibly intersecting the line
+    if ( axis > 0 ) ebbTree->prepare();
     ebbTree->getElementsNearLine( lineAxis, suspectFaces );
 
     // Intersect faces with the line
 
     map< double, TInters > & u2inters = paramOnLine2TInters[ axis ];
-    TIDSortedElemSet::iterator face = suspectFaces.begin();
+    vector<const SMDS_MeshElement*>::iterator face = suspectFaces.begin();
     for ( ; face != suspectFaces.end(); ++face )
     {
       // get face plane
@@ -1114,10 +1187,10 @@ void SMESH_ElementSearcherImpl::GetElementsNearLine( const gp_Ax1&
   ElementBndBoxTree*& ebbTree = _ebbTree[ type ];
   if ( !ebbTree )
     ebbTree = new ElementBndBoxTree( *_mesh, _elementType, _meshPartIt );
+  else
+    ebbTree->prepare();
 
-  TIDSortedElemSet suspectFaces; // elements possibly intersecting the line
-  ebbTree->getElementsNearLine( line, suspectFaces );
-  foundElems.assign( suspectFaces.begin(), suspectFaces.end());
+  ebbTree->getElementsNearLine( line, foundElems );
 }
 
 //=======================================================================
@@ -1135,10 +1208,10 @@ void SMESH_ElementSearcherImpl::GetElementsInSphere( const gp_XYZ&
   ElementBndBoxTree*& ebbTree = _ebbTree[ type ];
   if ( !ebbTree )
     ebbTree = new ElementBndBoxTree( *_mesh, _elementType, _meshPartIt );
+  else
+    ebbTree->prepare();
 
-  TIDSortedElemSet suspectFaces; // elements possibly intersecting the line
-  ebbTree->getElementsInSphere( center, radius, suspectFaces );
-  foundElems.assign( suspectFaces.begin(), suspectFaces.end() );
+  ebbTree->getElementsInSphere( center, radius, foundElems );
 }
 
 //=======================================================================
index ccdf3b1dadcf4b2ace94d8f4b3f8a254df3abdec..44047a694d54aa70b71ece72df8df0430ca468c5 100644 (file)
@@ -33,7 +33,6 @@
 #include <Utils_SALOME_Exception.hxx>
 #include <Standard_Failure.hxx>
 #include <Standard_ErrorHandler.hxx>
-#include <Basics_OCCTVersion.hxx>
 #include <utilities.h>
 
 // IMPORTANT: include this file _after_ OCC ones, else OCC_CATCH_SIGNALS can be undefined!
 #define OCC_CATCH_SIGNALS
 #endif
 
-// Define macros to catch and convert some of possible exceptions into text or SALOME_Exception
+// Define macros to catch and convert some of possible exceptions into text or SALOME_Exception.
+// WARNING: SALOME::SALOME_Exception (CORBA exception) is not treated here; to care about it add
+//          #define SMY_OWN_CATCH catch ( SALOME::SALOME_Exception & e ) { do_something(e); }
+//          before #include<SMESH_TryCatch.hxx>
+
 
 //-------------------------------------------------------------------------------------
 #define SMESH_TRY                               \
index f3a0a556cf1f207d763f09df3900c39a2aa20d0a..220e3d581eca960aa1bd84247f64381b0f89becc 100644 (file)
 #include <unistd.h>
 #endif
 
-OCCT_IMPLEMENT_STANDARD_RTTIEXT(_pyObject          ,Standard_Transient);
-OCCT_IMPLEMENT_STANDARD_RTTIEXT(_pyCommand         ,Standard_Transient);
-OCCT_IMPLEMENT_STANDARD_RTTIEXT(_pyHypothesisReader,Standard_Transient);
-OCCT_IMPLEMENT_STANDARD_RTTIEXT(_pyGen             ,_pyObject);
-OCCT_IMPLEMENT_STANDARD_RTTIEXT(_pyMesh            ,_pyObject);
-OCCT_IMPLEMENT_STANDARD_RTTIEXT(_pySubMesh         ,_pyObject);
-OCCT_IMPLEMENT_STANDARD_RTTIEXT(_pyMeshEditor      ,_pyObject);
-OCCT_IMPLEMENT_STANDARD_RTTIEXT(_pyHypothesis      ,_pyObject);
-OCCT_IMPLEMENT_STANDARD_RTTIEXT(_pySelfEraser      ,_pyObject);
-OCCT_IMPLEMENT_STANDARD_RTTIEXT(_pyGroup           ,_pyObject);
-OCCT_IMPLEMENT_STANDARD_RTTIEXT(_pyFilter          ,_pyObject);
-OCCT_IMPLEMENT_STANDARD_RTTIEXT(_pyAlgorithm       ,_pyHypothesis);
-OCCT_IMPLEMENT_STANDARD_RTTIEXT(_pyComplexParamHypo,_pyHypothesis);
-OCCT_IMPLEMENT_STANDARD_RTTIEXT(_pyNumberOfSegmentsHyp,_pyHypothesis);
-OCCT_IMPLEMENT_STANDARD_RTTIEXT(_pyLayerDistributionHypo,_pyHypothesis);
-OCCT_IMPLEMENT_STANDARD_RTTIEXT(_pySegmentLengthAroundVertexHyp,_pyHypothesis);
+IMPLEMENT_STANDARD_RTTIEXT(_pyObject          ,Standard_Transient);
+IMPLEMENT_STANDARD_RTTIEXT(_pyCommand         ,Standard_Transient);
+IMPLEMENT_STANDARD_RTTIEXT(_pyHypothesisReader,Standard_Transient);
+IMPLEMENT_STANDARD_RTTIEXT(_pyGen             ,_pyObject);
+IMPLEMENT_STANDARD_RTTIEXT(_pyMesh            ,_pyObject);
+IMPLEMENT_STANDARD_RTTIEXT(_pySubMesh         ,_pyObject);
+IMPLEMENT_STANDARD_RTTIEXT(_pyMeshEditor      ,_pyObject);
+IMPLEMENT_STANDARD_RTTIEXT(_pyHypothesis      ,_pyObject);
+IMPLEMENT_STANDARD_RTTIEXT(_pySelfEraser      ,_pyObject);
+IMPLEMENT_STANDARD_RTTIEXT(_pyGroup           ,_pyObject);
+IMPLEMENT_STANDARD_RTTIEXT(_pyFilter          ,_pyObject);
+IMPLEMENT_STANDARD_RTTIEXT(_pyAlgorithm       ,_pyHypothesis);
+IMPLEMENT_STANDARD_RTTIEXT(_pyComplexParamHypo,_pyHypothesis);
+IMPLEMENT_STANDARD_RTTIEXT(_pyNumberOfSegmentsHyp,_pyHypothesis);
+IMPLEMENT_STANDARD_RTTIEXT(_pyLayerDistributionHypo,_pyHypothesis);
+IMPLEMENT_STANDARD_RTTIEXT(_pySegmentLengthAroundVertexHyp,_pyHypothesis);
 
 using namespace std;
 using SMESH::TPythonDump;
@@ -922,7 +922,7 @@ Handle(_pyCommand) _pyGen::AddCommand( const TCollection_AsciiString& theCommand
           "Entity_Polygon", "Entity_Quad_Polygon", "Entity_Tetra", "Entity_Quad_Tetra",
           "Entity_Pyramid", "Entity_Quad_Pyramid",
           "Entity_Hexa", "Entity_Quad_Hexa", "Entity_TriQuad_Hexa",
-          "Entity_Penta", "Entity_Quad_Penta", "Entity_Hexagonal_Prism",
+          "Entity_Penta", "Entity_Quad_Penta", "Entity_BiQuad_Penta", "Entity_Hexagonal_Prism",
           "Entity_Polyhedra", "Entity_Quad_Polyhedra", "Entity_Ball" };
         if ( -1 < iGeom && iGeom < nbTypes )
           Threshold = SMESH + types[ iGeom ];
index 6fd991533bd9188f7e6fc9f06a404adb5399f633..4531a38ed792404cb3e787ba0ca29af5bc75738b 100644 (file)
@@ -40,8 +40,6 @@
 #include <vector>
 #include <set>
 
-#include <Basics_OCCTVersion.hxx>
-
 #include <SALOMEconfig.h>
 #include CORBA_CLIENT_HEADER(SALOMEDS)
 
@@ -160,7 +158,7 @@ public:
 
   bool AddAccessorMethod( _pyID theObjectID, const char* theAcsMethod );
 
-  OCCT_DEFINE_STANDARD_RTTIEXT(_pyCommand,Standard_Transient)
+  DEFINE_STANDARD_RTTIEXT(_pyCommand,Standard_Transient)
 };
 
 // -------------------------------------------------------------------------------------
@@ -200,7 +198,7 @@ public:
   virtual void ClearCommands();
   virtual void Free() {}
 
-  OCCT_DEFINE_STANDARD_RTTIEXT(_pyObject,Standard_Transient)
+  DEFINE_STANDARD_RTTIEXT(_pyObject,Standard_Transient)
 };
 
 // -------------------------------------------------------------------------------------
@@ -331,7 +329,7 @@ private:
   std::map< _AString, ExportedMeshData >    myFile2ExportedMesh;
   Handle( _pyHypothesisReader )             myHypReader;
 
-  OCCT_DEFINE_STANDARD_RTTIEXT(_pyGen,_pyObject)
+  DEFINE_STANDARD_RTTIEXT(_pyGen,_pyObject)
 };
 
 // -------------------------------------------------------------------------------------
@@ -372,7 +370,7 @@ private:
   static void AddMeshAccess( const Handle(_pyCommand)& theCommand )
   { theCommand->SetObject( theCommand->GetObject() + "." _pyMesh_ACCESS_METHOD ); }
 
-  OCCT_DEFINE_STANDARD_RTTIEXT(_pyMesh,_pyObject)
+  DEFINE_STANDARD_RTTIEXT(_pyMesh,_pyObject)
 };
 #undef _pyMesh_ACCESS_METHOD 
 
@@ -392,7 +390,7 @@ public:
   virtual void Flush() {}
   virtual bool CanClear();
 
-  OCCT_DEFINE_STANDARD_RTTIEXT(_pyMesh,_pyObject)
+  DEFINE_STANDARD_RTTIEXT(_pyMesh,_pyObject)
 };
 
 // -------------------------------------------------------------------------------------
@@ -476,7 +474,7 @@ public:
   //void ComputeSaved    ( const Handle(_pyCommand)& theComputeCommand );
 
 
-  OCCT_DEFINE_STANDARD_RTTIEXT(_pyHypothesis,_pyObject)
+  DEFINE_STANDARD_RTTIEXT(_pyHypothesis,_pyObject)
 };
 
 // -------------------------------------------------------------------------------------
@@ -493,7 +491,7 @@ public:
   virtual const char* AccessorMethod() const { return "GetAlgorithm()"; }
   virtual bool IsWrappable(const _pyID& theMesh) { return !myIsWrapped; }
 
-  OCCT_DEFINE_STANDARD_RTTIEXT(_pyAlgorithm,_pyHypothesis)
+  DEFINE_STANDARD_RTTIEXT(_pyAlgorithm,_pyHypothesis)
 };
 
 // -------------------------------------------------------------------------------------
@@ -508,7 +506,7 @@ public:
   virtual void Process( const Handle(_pyCommand)& theCommand);
   virtual void Flush();
 
-  OCCT_DEFINE_STANDARD_RTTIEXT(_pyComplexParamHypo,_pyHypothesis)
+  DEFINE_STANDARD_RTTIEXT(_pyComplexParamHypo,_pyHypothesis)
 };
 DEFINE_STANDARD_HANDLE (_pyComplexParamHypo, _pyHypothesis);
 
@@ -530,7 +528,7 @@ public:
                                   const _pyID&              theMesh);
   virtual void Free() { my1dHyp.Nullify(); }
 
-  OCCT_DEFINE_STANDARD_RTTIEXT(_pyLayerDistributionHypo,_pyHypothesis)
+  DEFINE_STANDARD_RTTIEXT(_pyLayerDistributionHypo,_pyHypothesis)
 };
 DEFINE_STANDARD_HANDLE (_pyLayerDistributionHypo, _pyHypothesis);
 
@@ -547,7 +545,7 @@ public:
                                   const _pyID&              theMesh);
   void Flush();
 
-  OCCT_DEFINE_STANDARD_RTTIEXT(_pyNumberOfSegmentsHyp,_pyHypothesis)
+  DEFINE_STANDARD_RTTIEXT(_pyNumberOfSegmentsHyp,_pyHypothesis)
 };
 DEFINE_STANDARD_HANDLE (_pyNumberOfSegmentsHyp, _pyHypothesis);
 
@@ -562,7 +560,7 @@ public:
   _pySegmentLengthAroundVertexHyp(const Handle(_pyCommand)& theCrCmd): _pyHypothesis(theCrCmd) {}
   virtual bool Addition2Creation( const Handle(_pyCommand)& theAdditionCmd,
                                   const _pyID&              theMesh);
-  OCCT_DEFINE_STANDARD_RTTIEXT(_pySegmentLengthAroundVertexHyp,_pyHypothesis)
+  DEFINE_STANDARD_RTTIEXT(_pySegmentLengthAroundVertexHyp,_pyHypothesis)
 };
 DEFINE_STANDARD_HANDLE (_pySegmentLengthAroundVertexHyp, _pyHypothesis);
 
@@ -581,7 +579,7 @@ public:
   virtual bool CanClear();
   static bool IsAliveCmd( const Handle(_pyCommand)& theCmd );
 
-  OCCT_DEFINE_STANDARD_RTTIEXT(_pySelfEraser,_pyObject)
+  DEFINE_STANDARD_RTTIEXT(_pySelfEraser,_pyObject)
 };
 DEFINE_STANDARD_HANDLE (_pySelfEraser, _pyObject);
 
@@ -603,7 +601,7 @@ public:
   void SetCreator( const Handle(_pyObject)& theCreator ) { myCreator = theCreator; }
   static bool CanBeArgOfMethod(const _AString& theMethodName);
 
-  OCCT_DEFINE_STANDARD_RTTIEXT(_pySubMesh,_pyObject)
+  DEFINE_STANDARD_RTTIEXT(_pySubMesh,_pyObject)
 };
 // -------------------------------------------------------------------------------------
 /*!
@@ -623,7 +621,7 @@ public:
   //virtual void Free() { myUsers.clear(); }
   const _pyID& GetNewID() const { return myNewID; }
 
-  OCCT_DEFINE_STANDARD_RTTIEXT(_pyFilter,_pyObject)
+  DEFINE_STANDARD_RTTIEXT(_pyFilter,_pyObject)
 };
 DEFINE_STANDARD_HANDLE (_pyFilter, _pyObject);
 
@@ -644,7 +642,7 @@ public:
   virtual bool CanClear();
   void RemovedWithContents();
 
-  OCCT_DEFINE_STANDARD_RTTIEXT(_pyGroup,_pySubMesh)
+  DEFINE_STANDARD_RTTIEXT(_pyGroup,_pySubMesh)
 };
 
 // -------------------------------------------------------------------------------------
@@ -659,7 +657,7 @@ public:
   _pyHypothesisReader();
   Handle(_pyHypothesis) GetHypothesis(const _AString&           hypType,
                                       const Handle(_pyCommand)& creationCmd) const;
-  OCCT_DEFINE_STANDARD_RTTIEXT(_pyHypothesisReader,Standard_Transient)
+  DEFINE_STANDARD_RTTIEXT(_pyHypothesisReader,Standard_Transient)
 };
 
 #endif
index cc842f215462cc31dedfe6acfedeca3f84b65e55..19c46da07fb5bd186afa1a98303547d8ecf23b39 100644 (file)
@@ -234,6 +234,7 @@ namespace SMESH
     case Entity_TriQuad_Hexa:      myStream<<"Entity_TriQuad_Hexa";      break;
     case Entity_Penta:             myStream<<"Entity_Penta";             break;
     case Entity_Quad_Penta:        myStream<<"Entity_Quad_Penta";        break;
+    case Entity_BiQuad_Penta:      myStream<<"Entity_BiQuad_Penta";      break;
     case Entity_Hexagonal_Prism:   myStream<<"Entity_Hexagonal_Prism";   break;
     case Entity_Polyhedra:         myStream<<"Entity_Polyhedra";         break;
     case Entity_Quad_Polyhedra:    myStream<<"Entity_Quad_Polyhedra";    break;
@@ -494,6 +495,17 @@ namespace SMESH
     switch (theVersion) {
     case SMESH::MED_V2_1: myStream << "SMESH.MED_V2_1"; break;
     case SMESH::MED_V2_2: myStream << "SMESH.MED_V2_2"; break;
+    case SMESH::MED_LATEST: myStream << "SMESH.MED_LATEST"; break;
+    case SMESH::MED_MINOR_0: myStream << "SMESH.MED_MINOR_0"; break;
+    case SMESH::MED_MINOR_1: myStream << "SMESH.MED_MINOR_1"; break;
+    case SMESH::MED_MINOR_2: myStream << "SMESH.MED_MINOR_2"; break;
+    case SMESH::MED_MINOR_3: myStream << "SMESH.MED_MINOR_3"; break;
+    case SMESH::MED_MINOR_4: myStream << "SMESH.MED_MINOR_4"; break;
+    case SMESH::MED_MINOR_5: myStream << "SMESH.MED_MINOR_5"; break;
+    case SMESH::MED_MINOR_6: myStream << "SMESH.MED_MINOR_6"; break;
+    case SMESH::MED_MINOR_7: myStream << "SMESH.MED_MINOR_7"; break;
+    case SMESH::MED_MINOR_8: myStream << "SMESH.MED_MINOR_8"; break;
+    case SMESH::MED_MINOR_9: myStream << "SMESH.MED_MINOR_9"; break;
     default: myStream << theVersion;
     }
     return *this;
index 739a4d904ffe1fd5f6cf0e7041e8ec17ab85ad1f..95c338377faa8b5584e8839fa7c2ece8b9fbbe30 100644 (file)
@@ -40,8 +40,6 @@
 #include <SALOMEDS_wrap.hxx>
 #include <GEOM_wrap.hxx>
 
-#include <Basics_OCCTVersion.hxx>
-
 #include <BRep_Tool.hxx>
 #include <Geom_CylindricalSurface.hxx>
 #include <Geom_Plane.hxx>
@@ -3941,16 +3939,6 @@ CORBA::Boolean FilterLibrary_i::Save()
   if ( myFileName == 0 || strlen( myFileName ) == 0 )
     return false;
 
-#if OCC_VERSION_MAJOR < 7
-  FILE* aOutFile = fopen( myFileName, "wt" );
-  if ( !aOutFile )
-    return false;
-
-  LDOM_XmlWriter aWriter( aOutFile );
-  aWriter.SetIndentation( 2 );
-  aWriter << myDoc;
-  fclose( aOutFile );
-#else
   std::filebuf fb;
   fb.open( myFileName, std::ios::out );
 
@@ -3960,7 +3948,6 @@ CORBA::Boolean FilterLibrary_i::Save()
   aWriter.SetIndentation( 2 );
   aWriter.Write( os, myDoc );
   fb.close();
-#endif
 
   TPythonDump()<<this<<".Save()";
   return true;
@@ -4109,7 +4096,7 @@ static const char** getFunctNames()
 #ifdef _DEBUG_
   // check if functName is complete, compilation failure means that enum FunctorType changed
   const int nbFunctors = sizeof(functName) / sizeof(const char*);
-  int _assert[( nbFunctors == SMESH::FT_Undefined + 1 ) ? 2 : -1 ]; _assert[0]=_assert[1];
+  int _assert[( nbFunctors == SMESH::FT_Undefined + 1 ) ? 2 : -1 ]; _assert[0]=_assert[1]=0;
 #endif
 
   return functName;
index 44cbff77a89b9974ac9e027ab25c9ce86307d1fd..f6877fa472404c875366b9c7cd7887e1adbeaa95 100644 (file)
  #define LoadLib( name ) LoadLibrary( name )
  #define GetProc GetProcAddress
  #define UnLoadLib( handle ) FreeLibrary( handle );
-#else
+#else // WIN32
  #define LibHandle void*
- #define LoadLib( name ) dlopen( name, RTLD_LAZY | RTLD_GLOBAL )
+ #ifdef DYNLOAD_LOCAL
+  #define LoadLib( name ) dlopen( name, RTLD_LAZY | RTLD_LOCAL )
+ #else // DYNLOAD_LOCAL
+  #define LoadLib( name ) dlopen( name, RTLD_LAZY | RTLD_GLOBAL )
+ #endif // DYNLOAD_LOCAL
  #define GetProc dlsym
  #define UnLoadLib( handle ) dlclose( handle );
-#endif
+#endif // WIN32
 
 #include "SMESH_Gen_i.hxx"
 #include "SMESH_version.h"
@@ -2560,7 +2564,7 @@ SMESH_Gen_i::ConcatenateCommon(const SMESH::ListOfIDSources& theMeshesArray,
         const char* typeNames[] = { "All","Nodes","Edges","Faces","Volumes","0DElems","Balls" };
         { // check of typeNames: compilation failure mains that NB_ELEMENT_TYPES changed:
           const int nbNames = sizeof(typeNames) / sizeof(const char*);
-          int _assert[( nbNames == SMESH::NB_ELEMENT_TYPES ) ? 2 : -1 ]; _assert[0]=_assert[1];
+          int _assert[( nbNames == SMESH::NB_ELEMENT_TYPES ) ? 2 : -1 ]; _assert[0]=_assert[1]=0;
         }
         string groupName = "Gr";
         SALOMEDS::SObject_wrap aMeshSObj = ObjectToSObject( myCurrentStudy, theMeshesArray[i] );
@@ -2968,8 +2972,19 @@ CORBA::Boolean SMESH_Gen_i::GetMEDVersion(const char* theFileName,
   theVersion = SMESH::MED_V2_1;
   MED::EVersion aVersion = MED::GetVersionId( theFileName );
   switch( aVersion ) {
-    case MED::eV2_1     : theVersion = SMESH::MED_V2_1; return true;
-    case MED::eV2_2     : theVersion = SMESH::MED_V2_2; return true;
+    case MED::eV2_1     : theVersion = SMESH::MED_V2_1;    return true;
+    case MED::eV2_2     : theVersion = SMESH::MED_V2_2;    return true;
+    case MED::eLATEST   : theVersion = SMESH::MED_LATEST;  return true;
+    case MED::eMINOR_0  : theVersion = SMESH::MED_MINOR_0; return true;
+    case MED::eMINOR_1  : theVersion = SMESH::MED_MINOR_1; return true;
+    case MED::eMINOR_2  : theVersion = SMESH::MED_MINOR_2; return true;
+    case MED::eMINOR_3  : theVersion = SMESH::MED_MINOR_3; return true;
+    case MED::eMINOR_4  : theVersion = SMESH::MED_MINOR_4; return true;
+    case MED::eMINOR_5  : theVersion = SMESH::MED_MINOR_5; return true;
+    case MED::eMINOR_6  : theVersion = SMESH::MED_MINOR_6; return true;
+    case MED::eMINOR_7  : theVersion = SMESH::MED_MINOR_7; return true;
+    case MED::eMINOR_8  : theVersion = SMESH::MED_MINOR_8; return true;
+    case MED::eMINOR_9  : theVersion = SMESH::MED_MINOR_9; return true;
     case MED::eVUnknown : return false;
   }
   return false;
index d9c4b0961d208e34d40bcacc65d9bff6804a6e37..d580262ded1d33b8a9dc214ee0e14d6ed3e21475 100644 (file)
@@ -474,8 +474,9 @@ SMESH::long_array* SMESH_GroupBase_i::GetListOfID()
   {
     int aSize = aGroupDS->Extent();
     aRes->length(aSize);
-    for (int i = 0; i < aSize; i++)
-      aRes[i] = aGroupDS->GetID(i+1);
+    SMDS_ElemIteratorPtr it = aGroupDS->GetElements();
+    for (int i = 0; it->more(); i++)
+      aRes[i] = it->next()->GetID();
 
     if ( 0 < aSize && aSize < 100 ) // for comfortable testing ;)
       std::sort( &aRes[0], &aRes[0]+aSize );
index 0ba74d70ffef6b3c0fb393d661c3a951ee6dbe9f..1c93dc90a0c9e5378c6ba66319096765394e5263 100644 (file)
@@ -64,7 +64,6 @@
 #include <Utils_CorbaException.hxx>
 #include <SALOMEDS_wrap.hxx>
 #include <SALOME_GenericObj_i.hh>
-#include <Basics_OCCTVersion.hxx>
 
 #include <BRepAdaptor_Surface.hxx>
 #include <BRep_Tool.hxx>
 #include <gp_Ax2.hxx>
 #include <gp_Vec.hxx>
 
-#if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
-#define NO_CAS_CATCH
-#endif
-
 #include <Standard_Failure.hxx>
-
-#ifdef NO_CAS_CATCH
 #include <Standard_ErrorHandler.hxx>
-#endif
 
 #include <sstream>
 #include <limits>
@@ -1151,6 +1143,10 @@ CORBA::Long SMESH_MeshEditor_i::AddVolume(const SMESH::long_array & IDsOfNodes)
                                         n[8],n[9],n[10],n[11],n[12],n[13],n[14],
                                         n[15],n[16],n[17],n[18],n[19]);
     break;
+  case 18:elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],n[6],n[7],
+                                        n[8],n[9],n[10],n[11],n[12],n[13],n[14],
+                                        n[15],n[16],n[17]);
+    break;
   case 27:elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],n[6],n[7],
                                         n[8],n[9],n[10],n[11],n[12],n[13],n[14],
                                         n[15],n[16],n[17],n[18],n[19],
@@ -3108,17 +3104,14 @@ SMESH_MeshEditor_i::mirror(TIDSortedElemSet &                  theElements,
   ::SMESH_MeshEditor::PGroupIDs groupIds =
       getEditor().Transform (*workElements, aTrsf, theCopy, theMakeGroups, theTargetMesh);
 
-  if ( theCopy && !myIsPreviewMode)
+  if ( !myIsPreviewMode )
   {
     if ( theTargetMesh )
-    {
       theTargetMesh->GetMeshDS()->Modified();
-    }
     else
-    {
       declareMeshModified( /*isReComputeSafe=*/false );
-    }
   }
+
   return theMakeGroups ? getGroups(groupIds.get()) : 0;
 
   SMESH_CATCH( SMESH::throwCorbaException );
@@ -3375,16 +3368,12 @@ SMESH_MeshEditor_i::translate(TIDSortedElemSet        & theElements,
   ::SMESH_MeshEditor::PGroupIDs groupIds =
       getEditor().Transform (*workElements, aTrsf, theCopy, theMakeGroups, theTargetMesh);
 
-  if ( theCopy && !myIsPreviewMode )
+  if ( !myIsPreviewMode )
   {
     if ( theTargetMesh )
-    {
       theTargetMesh->GetMeshDS()->Modified();
-    }
     else
-    {
       declareMeshModified( /*isReComputeSafe=*/false );
-    }
   }
 
   return theMakeGroups ? getGroups(groupIds.get()) : 0;
@@ -3632,7 +3621,7 @@ SMESH_MeshEditor_i::rotate(TIDSortedElemSet &        theElements,
   ::SMESH_MeshEditor::PGroupIDs groupIds =
       getEditor().Transform (*workElements, aTrsf, theCopy, theMakeGroups, theTargetMesh);
 
-  if ( theCopy && !myIsPreviewMode)
+  if ( !myIsPreviewMode)
   {
     if ( theTargetMesh ) theTargetMesh->GetMeshDS()->Modified();
     else                 declareMeshModified( /*isReComputeSafe=*/false );
@@ -3893,7 +3882,6 @@ SMESH_MeshEditor_i::scale(SMESH::SMESH_IDSource_ptr  theObject,
   };
   gp_Trsf aTrsf;
 
-#if OCC_VERSION_LARGE > 0x06070100
   // fight against orthogonalization
   // aTrsf.SetValues( S[0], 0,    0,    thePoint.x * (1-S[0]),
   //                  0,    S[1], 0,    thePoint.y * (1-S[1]),
@@ -3906,13 +3894,6 @@ SMESH_MeshEditor_i::scale(SMESH::SMESH_IDSource_ptr  theObject,
                 thePoint.z * (1-S[2]));
   M.SetDiagonal( S[0], S[1], S[2] );
 
-#else
-  double tol = std::numeric_limits<double>::max();
-  aTrsf.SetValues( S[0], 0,    0,    thePoint.x * (1-S[0]),
-                   0,    S[1], 0,    thePoint.y * (1-S[1]),
-                   0,    0,    S[2], thePoint.z * (1-S[2]),   tol, tol);
-#endif
-
   TIDSortedElemSet  copyElements;
   TIDSortedElemSet* workElements = &elements;
   if ( myIsPreviewMode )
@@ -3932,7 +3913,7 @@ SMESH_MeshEditor_i::scale(SMESH::SMESH_IDSource_ptr  theObject,
   ::SMESH_MeshEditor::PGroupIDs groupIds =
       getEditor().Transform (*workElements, aTrsf, theCopy, theMakeGroups, theTargetMesh);
 
-  if ( theCopy && !myIsPreviewMode )
+  if ( !myIsPreviewMode )
   {
     if ( theTargetMesh ) theTargetMesh->GetMeshDS()->Modified();
     else                 declareMeshModified( /*isReComputeSafe=*/false );
index a075dadce83d21437eebba69f9bbb11eeac2a505..c4393b108a48d5ef6cc3aa30db764a06704f540a 100644 (file)
@@ -3022,6 +3022,7 @@ void SMESH_Mesh_i::ExportToMEDX (const char*        file,
                                  CORBA::Boolean     autoDimension)
   throw(SALOME::SALOME_Exception)
 {
+  //MESSAGE("SMESH::MED_VERSION:"<< theVersion);
   SMESH_TRY;
   if ( _preMeshInfo )
     _preMeshInfo->FullLoadFromFile();
@@ -3048,6 +3049,7 @@ void SMESH_Mesh_i::ExportToMED (const char*        file,
                                 SMESH::MED_VERSION theVersion)
   throw(SALOME::SALOME_Exception)
 {
+  //MESSAGE("SMESH::MED_VERSION:"<< theVersion);
   ExportToMEDX(file,auto_groups,theVersion,true);
 }
 
@@ -3061,7 +3063,8 @@ void SMESH_Mesh_i::ExportMED (const char* file,
                               CORBA::Boolean auto_groups)
   throw(SALOME::SALOME_Exception)
 {
-  ExportToMEDX(file,auto_groups,SMESH::MED_V2_2,true);
+  //MESSAGE("SMESH::MED_VERSION:"<< SMESH::MED_LATEST);
+  ExportToMEDX(file,auto_groups,SMESH::MED_LATEST,true);
 }
 
 //================================================================================
@@ -3628,7 +3631,8 @@ void SMESH_Mesh_i::ExportPartToSTL(::SMESH::SMESH_IDSource_ptr meshPart,
 
 void SMESH_Mesh_i::ExportCGNS(::SMESH::SMESH_IDSource_ptr meshPart,
                               const char*                 file,
-                              CORBA::Boolean              overwrite)
+                              CORBA::Boolean              overwrite,
+                              CORBA::Boolean              groupElemsByType)
   throw (SALOME::SALOME_Exception)
 {
 #ifdef WITH_CGNS
@@ -3646,8 +3650,12 @@ void SMESH_Mesh_i::ExportCGNS(::SMESH::SMESH_IDSource_ptr meshPart,
     CORBA::String_var name = so->GetName();
     meshName = name.in();
   }
+  SMESH_TRY;
+
   SMESH_MeshPartDS partDS( meshPart );
-  _impl->ExportCGNS(file, &partDS, meshName.c_str() );
+  _impl->ExportCGNS(file, &partDS, meshName.c_str(), groupElemsByType );
+
+  SMESH_CATCH( SMESH::throwCorbaException );
 
   TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportCGNS( "
                 << meshPart<< ", r'" << file << "', " << overwrite << ")";
@@ -4771,6 +4779,35 @@ CORBA::Long SMESH_Mesh_i::FindElementByNodes(const SMESH::long_array& nodes)
   return elemID;
 }
 
+//================================================================================
+/*!
+ * \brief Return elements including all given nodes.
+ */
+//================================================================================
+
+SMESH::long_array* SMESH_Mesh_i::GetElementsByNodes(const SMESH::long_array& nodes,
+                                                    SMESH::ElementType       elemType)
+{
+  if ( _preMeshInfo )
+    _preMeshInfo->FullLoadFromFile();
+
+  SMESH::long_array_var result = new SMESH::long_array();
+
+  if ( SMESHDS_Mesh* mesh = _impl->GetMeshDS() )
+  {
+    vector< const SMDS_MeshNode * > nn( nodes.length() );
+    for ( CORBA::ULong i = 0; i < nodes.length(); ++i )
+      nn[i] = mesh->FindNode( nodes[i] );
+
+    std::vector<const SMDS_MeshElement *> elems;
+    mesh->GetElementsByNodes( nn, elems, (SMDSAbs_ElementType) elemType );
+    result->length( elems.size() );
+    for ( size_t i = 0; i < elems.size(); ++i )
+      result[i] = elems[i]->GetID();
+  }
+  return result._retn();
+}
+
 //=============================================================================
 /*!
  * Returns true if given element is polygon
index 8aaa79bae4201174e2019ce25b9c2f7b2d427c81..39fd2aa1cd12d618a8ef6534acdb21ca6784b293 100644 (file)
@@ -251,7 +251,8 @@ public:
   void ExportSTL( const char* file, bool isascii ) throw (SALOME::SALOME_Exception);
   void ExportCGNS(SMESH::SMESH_IDSource_ptr meshPart,
                   const char*               file,
-                  CORBA::Boolean            overwrite) throw (SALOME::SALOME_Exception);
+                  CORBA::Boolean            overwrite,
+                  CORBA::Boolean            groupElemsByType) throw (SALOME::SALOME_Exception);
   void ExportGMF(SMESH::SMESH_IDSource_ptr meshPart,
                  const char*               file,
                  CORBA::Boolean            withRequiredGroups) throw (SALOME::SALOME_Exception);
@@ -536,8 +537,8 @@ public:
    * Returns true if given node is medium node
    * in one of quadratic elements
    */
-  CORBA::Boolean IsMediumNodeOfAnyElem(CORBA::Long idn,
-                                       SMESH::ElementType theElemType);
+  CORBA::Boolean IsMediumNodeOfAnyElem(CORBA::Long        idn,
+                                       SMESH::ElementType elemType);
 
   /*!
    * Returns number of edges for given element
@@ -563,6 +564,12 @@ public:
    */
   CORBA::Long FindElementByNodes(const SMESH::long_array& nodes);
 
+  /*!
+   * Return elements including all given nodes.
+   */
+  SMESH::long_array* GetElementsByNodes(const SMESH::long_array& nodes,
+                                        SMESH::ElementType       elemType);
+
   /*!
    * Returns true if given element is polygon
    */
index ca5bcd0d2e0c74d85f482bd6e15242916996fef0..70dab5de7d79f0f008e2766148c0044d93519bea 100644 (file)
@@ -295,9 +295,7 @@ SMESH::point_array*
   }
   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) {
index 057506db66b0918727a85fc8d51781c0741c893f..b57d2b4df013123244a214cd3778232480c501b2 100644 (file)
@@ -22,8 +22,6 @@
 # scripts / static
 SET(_bin_SCRIPTS
   smesh.py
-  batchmode_smesh.py
-  batchmode_mefisto.py
   ex00_all.py
   ex01_cube2build.py
   ex02_cube2primitive.py
diff --git a/src/SMESH_SWIG/batchmode_mefisto.py b/src/SMESH_SWIG/batchmode_mefisto.py
deleted file mode 100644 (file)
index baf57ef..0000000
+++ /dev/null
@@ -1,127 +0,0 @@
-#  -*- coding: iso-8859-1 -*-
-# Copyright (C) 2007-2016  CEA/DEN, EDF R&D, OPEN CASCADE
-#
-# Copyright (C) 2003-2007  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, or (at your option) any later version.
-#
-# 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
-#
-
-import os
-import re
-
-import batchmode_salome
-import batchmode_geompy
-import batchmode_smesh
-from salome.StdMeshers import StdMeshersBuilder
-
-smesh = batchmode_smesh.smesh
-smesh.SetCurrentStudy(batchmode_salome.myStudy)
-
-def CreateMesh (theFileName, area, len = None, nbseg = None):
-    
-    if not(os.path.isfile(theFileName)) or re.search("\.brep$", theFileName) is None :
-        print "Incorrect file name !"
-        return
-
-    if (len is None) and (nbseg is None):
-        print "Define length or number of segments !"
-        return
-
-    if (len is not None) and (nbseg is not None):
-        print "Only one Hypothesis (from length and number of segments) can be defined !"
-        return
-
-    
-    # ----  Import shape from BREP file and add it to the study  
-    shape_mesh = batchmode_geompy.Import(theFileName, "BREP")
-    Id_shape = batchmode_geompy.addToStudy(shape_mesh, "shape_mesh")
-
-
-    # ---- SMESH
-    print "-------------------------- create mesh"
-    mesh = smesh.Mesh(shape_mesh)
-      
-    print "-------------------------- create Hypothesis"
-    if (len is not None):
-        print "-------------------------- LocalLength"
-        algoReg = mesh.Segment()
-        hypLength1 = algoReg.LocalLength(len)
-        print "Hypothesis type : ", hypLength1.GetName()
-        print "Hypothesis ID   : ", hypLength1.GetId()
-        print "Hypothesis Value: ", hypLength1.GetLength()
-    
-    if (nbseg is not None):   
-        print "-------------------------- NumberOfSegments"
-        algoReg = mesh.Segment()
-        hypNbSeg1 = algoReg.NumberOfSegments(nbseg)
-        print "Hypothesis type : ", hypNbSeg1.GetName()
-        print "Hypothesis ID   : ", hypNbSeg1.GetId()
-        print "Hypothesis Value: ", hypNbSeg1.GetNumberOfSegments()
-
-    if (area == "LengthFromEdges"):
-        print "-------------------------- LengthFromEdges"
-        algoMef = mesh.Triangle()
-        hypLengthFromEdges = algoMef.LengthFromEdges(1)
-        print "Hypothesis type     : ", hypLengthFromEdges.GetName()
-        print "Hypothesis ID       : ", hypLengthFromEdges.GetId()
-        print "LengthFromEdges Mode: ", hypLengthFromEdges.GetMode()
-       
-    else:
-        print "-------------------------- MaxElementArea"
-        algoMef = mesh.Triangle()
-        hypArea1 = algoMef.MaxElementArea(area)
-        print "Hypothesis type : ", hypArea1.GetName()
-        print "Hypothesis ID   : ", hypArea1.GetId()
-        print "Hypothesis Value: ", hypArea1.GetMaxElementArea()
-              
-    
-    print "-------------------------- Regular_1D"
-    listHyp = algoReg.GetCompatibleHypothesis()
-    for hyp in listHyp:
-        print hyp
-    
-    print "Algo name: ", algoReg.GetName()
-    print "Algo ID  : ", algoReg.GetId()
-   
-    print "-------------------------- MEFISTO_2D"
-    listHyp = algoMef.GetCompatibleHypothesis()
-    for hyp in listHyp:
-        print hyp
-        
-    print "Algo name: ", algoMef.GetName()
-    print "Algo ID  : ", algoMef.GetId()
-
-
-    # ---- add hypothesis to shape
-
-    print "-------------------------- compute mesh"
-    ret = mesh.Compute()
-    print  "Compute Mesh .... ", 
-    print ret
-    log = mesh.GetLog(0); # no erase trace
-    #for linelog in log:
-    #    print linelog
-
-    print "------------ INFORMATION ABOUT MESH ------------"
-    
-    print "Number of nodes    : ", mesh.NbNodes()
-    print "Number of edges    : ", mesh.NbEdges()
-    print "Number of faces    : ", mesh.NbFaces()
-    print "Number of triangles: ", mesh.NbTriangles()
-
-    return mesh
diff --git a/src/SMESH_SWIG/batchmode_smesh.py b/src/SMESH_SWIG/batchmode_smesh.py
deleted file mode 100644 (file)
index c31f82a..0000000
+++ /dev/null
@@ -1,324 +0,0 @@
-#  -*- coding: iso-8859-1 -*-
-# Copyright (C) 2007-2016  CEA/DEN, EDF R&D, OPEN CASCADE
-#
-# Copyright (C) 2003-2007  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, or (at your option) any later version.
-#
-# 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   : batchmode_smesh.py
-#  Author : Oksana TCHEBANOVA
-#  Module : SMESH
-#  $Header$
-#
-from batchmode_salome import *
-from batchmode_geompy import ShapeType
-import SMESH
-
-#--------------------------------------------------------------------------
-modulecatalog = naming_service.Resolve("/Kernel/ModulCatalog")
-
-smesh = lcc.FindOrLoadComponent("FactoryServer", "SMESH")
-smesh.SetCurrentStudy(myStudy)
-myStudyBuilder = myStudy.NewBuilder()
-
-if myStudyBuilder is None:
-       raise RuntimeError, " Null myStudyBuilder"
-
-father = myStudy.FindComponent("SMESH")
-if father is None:
-        father = myStudyBuilder.NewComponent("SMESH")
-        FName = myStudyBuilder.FindOrCreateAttribute(father, "AttributeName")
-       Comp = modulecatalog.GetComponent("SMESH")
-       FName.SetValue(Comp._get_componentusername())
-       aPixmap = myStudyBuilder.FindOrCreateAttribute(father, "AttributePixMap")
-       aPixmap.SetPixMap("ICON_OBJBROWSER_Mesh")
-
-myStudyBuilder.DefineComponentInstance(father,smesh)
-
-mySComponentMesh = father._narrow(SALOMEDS.SComponent)
-
-Tag_HypothesisRoot  = 1
-Tag_AlgorithmsRoot  = 2
-  
-Tag_RefOnShape      = 1
-Tag_RefOnAppliedHypothesis = 2
-Tag_RefOnAppliedAlgorithms = 3
-  
-Tag_SubMeshOnVertex = 4
-Tag_SubMeshOnEdge = 5
-Tag_SubMeshOnFace = 6
-Tag_SubMeshOnSolid = 7
-Tag_SubMeshOnCompound = 8
-
-Tag = {"HypothesisRoot":1,"AlgorithmsRoot":2,"RefOnShape":1,"RefOnAppliedHypothesis":2,"RefOnAppliedAlgorithms":3,"SubMeshOnVertex":4,"SubMeshOnEdge":5,"SubMeshOnFace":6,"SubMeshOnSolid":7,"SubMeshOnCompound":8}
-
-#------------------------------------------------------------
-def Init():
-        pass
-#------------------------------------------------------------
-def AddNewMesh(IOR):
-       # VSR: added temporarily - objects are published automatically by the engine
-       aSO = myStudy.FindObjectIOR( IOR )
-       if aSO is not None:
-               return aSO.GetID()
-       # VSR ######################################################################
-       
-       res,HypothesisRoot = mySComponentMesh.FindSubObject ( Tag_HypothesisRoot )
-       if HypothesisRoot is None or res == 0:
-               HypothesisRoot = myStudyBuilder.NewObjectToTag(mySComponentMesh, Tag_HypothesisRoot)
-               aName = myStudyBuilder.FindOrCreateAttribute(HypothesisRoot, "AttributeName")
-               aName.SetValue("Hypotheses")
-               aPixmap = myStudyBuilder.FindOrCreateAttribute(HypothesisRoot, "AttributePixMap")
-               aPixmap.SetPixMap( "mesh_tree_hypo.png" )
-               aSelAttr = myStudyBuilder.FindOrCreateAttribute(HypothesisRoot, "AttributeSelectable")
-               aSelAttr.SetSelectable(0)
-
-       res, AlgorithmsRoot = mySComponentMesh.FindSubObject (Tag_AlgorithmsRoot)
-       if AlgorithmsRoot is None  or res == 0:
-               AlgorithmsRoot = myStudyBuilder.NewObjectToTag (mySComponentMesh, Tag_AlgorithmsRoot)
-               aName = myStudyBuilder.FindOrCreateAttribute(AlgorithmsRoot, "AttributeName")
-               aName.SetValue("Algorithms")
-               aPixmap = myStudyBuilder.FindOrCreateAttribute(AlgorithmsRoot, "AttributePixMap")
-               aPixmap.SetPixMap( "mesh_tree_algo.png" )
-               aSelAttr = myStudyBuilder.FindOrCreateAttribute(AlgorithmsRoot, "AttributeSelectable")
-               aSelAttr.SetSelectable(0)
-
-       HypothesisRoot = HypothesisRoot._narrow(SALOMEDS.SObject)
-       newMesh = myStudyBuilder.NewObject(mySComponentMesh)
-       aPixmap = myStudyBuilder.FindOrCreateAttribute(newMesh, "AttributePixMap")
-       aPixmap.SetPixMap( "mesh_tree_mesh.png" )
-       anIOR = myStudyBuilder.FindOrCreateAttribute(newMesh, "AttributeIOR")
-       anIOR.SetValue(IOR)
-       return newMesh.GetID()
-
-#------------------------------------------------------------  
-def AddNewHypothesis(IOR):
-       # VSR: added temporarily - objects are published automatically by the engine
-       aSO = myStudy.FindObjectIOR( IOR )
-       if aSO is not None:
-               return aSO.GetID()
-       # VSR ######################################################################
-
-       res, HypothesisRoot = mySComponentMesh.FindSubObject (Tag_HypothesisRoot)
-       if HypothesisRoot is None or res == 0:
-               HypothesisRoot = myStudyBuilder.NewObjectToTag (mySComponentMesh, Tag_HypothesisRoot)
-               aName = myStudyBuilder.FindOrCreateAttribute(HypothesisRoot, "AttributeName")
-               aName.SetValue("Hypotheses")
-               aSelAttr = myStudyBuilder.FindOrCreateAttribute(HypothesisRoot, "AttributeSelectable")
-               aSelAttr.SetSelectable(0)
-               aPixmap = myStudyBuilder.FindOrCreateAttribute(HypothesisRoot, "AttributePixMap")
-               aPixmap.SetPixMap( "mesh_tree_hypo.png" )
-       # Add New Hypothesis
-       newHypo = myStudyBuilder.NewObject(HypothesisRoot)
-       aPixmap = myStudyBuilder.FindOrCreateAttribute(newHypo, "AttributePixMap")
-       H = orb.string_to_object(IOR)
-       aType = H.GetName()
-       aPixmap.SetPixMap( "mesh_tree_hypo.png_" + aType )
-       anIOR = myStudyBuilder.FindOrCreateAttribute(newHypo, "AttributeIOR")
-       anIOR.SetValue(IOR)
-       return newHypo.GetID()
-
-#------------------------------------------------------------
-def AddNewAlgorithms(IOR):
-       # VSR: added temporarily - objects are published automatically by the engine
-       aSO = myStudy.FindObjectIOR( IOR )
-       if aSO is not None:
-               return aSO.GetID()
-       # VSR ######################################################################
-
-       res, AlgorithmsRoot = mySComponentMesh.FindSubObject (Tag_AlgorithmsRoot)
-       if  AlgorithmsRoot is None or res == 0:
-               AlgorithmsRoot = myStudyBuilde.NewObjectToTag (mySComponentMesh, Tag_AlgorithmsRoot)
-               aName = myStudyBuilder.FindOrCreateAttribute(AlgorithmsRoot, "AttributeName")
-               aName.SetValue("Algorithms")
-               aSelAttr = myStudyBuilder.FindOrCreateAttribute(AlgorithmsRoot, "AttributeSelectable")
-               aSelAttr.SetSelectable(0)
-               aPixmap = myStudyBuilder.FindOrCreateAttribute(AlgorithmsRoot, "AttributePixMap")
-               aPixmap.SetPixMap( "mesh_tree_algo.png" )
-
-  # Add New Algorithms
-       newHypo = myStudyBuilder.NewObject(AlgorithmsRoot)
-       aPixmap = myStudyBuilder.FindOrCreateAttribute(newHypo, "AttributePixMap")
-       aPixmap = anAttr._narrow(SALOMEDS.AttributePixMap)
-       H = orb.string_to_object(IOR)
-       aType = H.GetName();    #QString in fact
-       aPixmap.SetPixMap( "mesh_tree_algo.png_" + aType )
-       anIOR = myStudyBuilder.FindOrCreateAttribute(newHypo, "AttributeIOR")
-       anIOR.SetValue(IOR)
-       return newHypo.GetID()
-
-
-#------------------------------------------------------------
-def SetShape(ShapeEntry, MeshEntry):
-       SO_MorSM = myStudy.FindObjectID( MeshEntry )
-       SO_GeomShape = myStudy.FindObjectID( ShapeEntry )
-
-       if SO_MorSM is not None and SO_GeomShape is not None :
-               # VSR: added temporarily - shape reference is published automatically by the engine
-               res, Ref = SO_MorSM.FindSubObject( Tag_RefOnShape )
-               if res == 1 :
-                       return
-               # VSR ######################################################################
-       
-               SO = myStudyBuilder.NewObjectToTag (SO_MorSM, Tag_RefOnShape)
-               myStudyBuilder.Addreference (SO,SO_GeomShape)
-
-
-#------------------------------------------------------------
-def SetHypothesis(Mesh_Or_SubMesh_Entry, Hypothesis_Entry):
-  SO_MorSM = myStudy.FindObjectID( Mesh_Or_SubMesh_Entry )
-  SO_Hypothesis =  myStudy.FindObjectID( Hypothesis_Entry )
-
-  if  SO_MorSM is not None and SO_Hypothesis is not None : 
-    
-        #Find or Create Applied Hypothesis root
-       res, AHR = SO_MorSM.FindSubObject (Tag_RefOnAppliedHypothesis)
-       if  AHR is None or res == 0: 
-               AHR = myStudyBuilder.NewObjectToTag (SO_MorSM, Tag_RefOnAppliedHypothesis)
-               aName = myStudyBuilder.FindOrCreateAttribute(AHR, "AttributeName")
-               
-               # The same name as in SMESH_Mesh_i::AddHypothesis() ##################
-               aName.SetValue("Applied hypotheses")
-               
-               aSelAttr = myStudyBuilder.FindOrCreateAttribute(AHR, "AttributeSelectable")
-               aSelAttr.SetSelectable(0)
-               aPixmap = myStudyBuilder.FindOrCreateAttribute(AHR, "AttributePixMap")
-               aPixmap.SetPixMap( "mesh_tree_hypo.png" )
-               
-       # VSR: added temporarily - reference to applied hypothesis is published automatically by the engine
-       else :
-               it = myStudy.NewChildIterator(AHR)
-               while it.More() :
-                       res, Ref = it.Value().ReferencedObject()
-                       if res and Ref is not None and Ref.GetID() == Hypothesis_Entry :
-                               return
-                       it.Next()
-       # VSR ######################################################################
-       
-       SO = myStudyBuilder.NewObject(AHR)
-       myStudyBuilder.Addreference (SO,SO_Hypothesis)
-
-#------------------------------------------------------------
-def SetAlgorithms(Mesh_Or_SubMesh_Entry, Algorithms_Entry):
-    SO_MorSM = myStudy.FindObjectID( Mesh_Or_SubMesh_Entry )
-    SO_Algorithms = myStudy.FindObjectID( Algorithms_Entry )
-    if  SO_MorSM != None and SO_Algorithms != None : 
-       #Find or Create Applied Algorithms root
-       res, AHR = SO_MorSM.FindSubObject (Tag_RefOnAppliedAlgorithms)
-       if AHR is None or res == 0: 
-               AHR = myStudyBuilder.NewObjectToTag (SO_MorSM, Tag_RefOnAppliedAlgorithms)
-               aName = myStudyBuilder.FindOrCreateAttribute(AHR, "AttributeName")
-
-               # The same name as in SMESH_Mesh_i::AddHypothesis() ##################
-               aName.SetValue("Applied algorithms")
-               
-               aSelAttr = myStudyBuilder.FindOrCreateAttribute(AHR, "AttributeSelectable")
-               aSelAttr.SetSelectable(0)
-               aPixmap = myStudyBuilder.FindOrCreateAttribute(AHR, "AttributePixMap")
-               aPixmap.SetPixMap( "mesh_tree_algo.png" )
-                       
-       # VSR: added temporarily - reference to applied hypothesis is published automatically by the engine
-       else :
-               it = myStudy.NewChildIterator(AHR)
-               while it.More() :
-                       res, Ref = it.Value().ReferencedObject()
-                       if res and Ref is not None and Ref.GetID() == Algorithms_Entry :
-                               return
-                       it.Next()
-       # VSR ######################################################################
-       
-       SO = myStudyBuilder.NewObject(AHR)
-       myStudyBuilder.Addreference (SO,SO_Algorithms)
-  
-
-#------------------------------------------------------------
-def UnSetHypothesis( Applied_Hypothesis_Entry ):
-       SO_Applied_Hypothesis = myStudy.FindObjectID( Applied_Hypothesis_Entry )
-       if SO_Applied_Hypothesis : 
-               myStudyBuilder.RemoveObject(SO_Applied_Hypothesis)
-       
-
-#------------------------------------------------------------
-def AddSubMesh ( SO_Mesh_Entry, SM_IOR, ST):
-       # VSR: added temporarily - objects are published automatically by the engine
-       aSO = myStudy.FindObjectIOR( SM_IOR )
-       if aSO is not None:
-               return aSO.GetID()
-       # VSR ######################################################################
-       
-       SO_Mesh = myStudy.FindObjectID( SO_Mesh_Entry )
-       if ( SO_Mesh ) : 
-    
-               if  ST == ShapeType["COMPSOLID"] : 
-                       Tag_Shape = Tag_SubMeshOnSolid
-                       Name = "SubMeshes on Solid"
-               elif ST == ShapeType["FACE"] :
-                       Tag_Shape = Tag_SubMeshOnFace
-                       Name = "SubMeshes on Face"
-               elif ST == ShapeType["EDGE"] :
-                       Tag_Shape = Tag_SubMeshOnEdge
-                       Name = "SubMeshes on Edge"
-               elif ST == ShapeType["VERTEX"] :
-                       Tag_Shape = Tag_SubMeshOnVertex
-                       Name = "SubMeshes on Vertex"
-               else :
-                       Tag_Shape = Tag_SubMeshOnCompound
-                       Name = "SubMeshes on Compound"
-               
-               res, SubmeshesRoot = SO_Mesh.FindSubObject (Tag_Shape)
-               if SubmeshesRoot is None or res == 0:
-                       SubmeshesRoot = myStudyBuilder.NewObjectToTag (SO_Mesh, Tag_Shape)
-                       aName = myStudyBuilder.FindOrCreateAttribute(SubmeshesRoot, "AttributeName")
-                       aName.SetValue(Name)
-                       aSelAttr = myStudyBuilder.FindOrCreateAttribute(SubmeshesRoot, "AttributeSelectable")
-                       aSelAttr.SetSelectable(0)
-               
-               SO = myStudyBuilder.NewObject (SubmeshesRoot)
-               anIOR = myStudyBuilder.FindOrCreateAttribute(SO, "AttributeIOR")
-               anIOR.SetValue(SM_IOR)
-               return  SO.GetID()
-
-       return None
-
-#------------------------------------------------------------
-def AddSubMeshOnShape (Mesh_Entry, GeomShape_Entry, SM_IOR, ST) :
-       # VSR: added temporarily - objects are published automatically by the engine
-       aSO = myStudy.FindObjectIOR( SM_IOR )
-       if aSO is not None:
-               return aSO.GetID()
-       # VSR ######################################################################
-       SO_GeomShape = myStudy.FindObjectID( GeomShape_Entry )
-       if  SO_GeomShape != None : 
-               SM_Entry = AddSubMesh (Mesh_Entry,SM_IOR,ST)
-               SO_SM = myStudy.FindObjectID( SM_Entry )
-
-               if  SO_SM != None :
-                       SetShape (GeomShape_Entry, SM_Entry)
-                       return SM_Entry
-
-       return None
-
-
-#------------------------------------------------------------
-def SetName(Entry, Name):
-       SO = myStudy.FindObjectID( Entry )
-       if SO != None : 
-               aName = myStudyBuilder.FindOrCreateAttribute(SO, "AttributeName")
-               aName.SetValue(Name)
index 938d0eac100553a1fd32ff368f33b7ba5c5329d3..72e0f631a0faeee7e48106daea43d0edc3cb715c 100644 (file)
@@ -36,8 +36,11 @@ import os
 # Values
 # ------
 
+tmpDir = os.getenv('SALOME_TMP_DIR', '/tmp')
+print "Output directory:", tmpDir
+
 # Path for ".med" files
-path = "/tmp/ex29_%s_" % os.getenv('USER','unknown')
+path = os.path.join( tmpDir, "ex29_%s_" % os.getenv('USER','unknown'))
 
 # Name of the shape and the mesh
 name = "Carre"
index d87d0d5539a7083c97d429bd129a6d06e99797fe..f2bbcaccc85618c7ab66d1124a8f8c405393f377 100644 (file)
@@ -1793,9 +1793,14 @@ class Mesh:
     #  @param auto_groups boolean parameter for creating/not creating
     #  the groups Group_On_All_Nodes, Group_On_All_Faces, ... ;
     #  the typical use is auto_groups=False.
-    #  @param version MED format version (MED_V2_1 or MED_V2_2,
-    #                 the latter meaning any current version). The parameter is
-    #                 obsolete since MED_V2_1 is no longer supported.
+    #  @param version MED format version
+    #         - MED_V2_1 is obsolete.
+    #         - MED_V2_2 means current version (kept for compatibility reasons)
+    #         - MED_LATEST means current version.
+    #         - MED_MINOR_x where x from 0 to 9 indicates the minor version of MED
+    #           to use for writing MED files, for backward compatibility :
+    #           for instance, with SALOME 8.4 use MED 3.2 (minor=2) instead of 3.3,
+    #           to allow the file to be read with SALOME 8.3.
     #  @param overwrite boolean parameter for overwriting/not overwriting the file
     #  @param meshPart a part of mesh (group, sub-mesh) to export instead of the mesh
     #  @param autoDimension if @c True (default), a space dimension of a MED mesh can be either
@@ -1811,7 +1816,7 @@ class Mesh:
     #         - 'f' stands for "_faces _" field;
     #         - 's' stands for "_solids _" field.
     #  @ingroup l2_impexp
-    def ExportMED(self, f, auto_groups=0, version=MED_V2_2,
+    def ExportMED(self, f, auto_groups=0, version=MED_LATEST,
                   overwrite=1, meshPart=None, autoDimension=True, fields=[], geomAssocFields=''):
         if meshPart or fields or geomAssocFields:
             unRegister = genObjUnRegister()
@@ -1879,8 +1884,11 @@ class Mesh:
     #  @param f is the file name
     #  @param overwrite boolean parameter for overwriting/not overwriting the file
     #  @param meshPart a part of mesh (group, sub-mesh) to export instead of the mesh
+    #  @param groupElemsByType if true all elements of same entity type are exported at ones,
+    #         else elements are exported in order of their IDs which can cause creation
+    #         of multiple cgns sections
     #  @ingroup l2_impexp
-    def ExportCGNS(self, f, overwrite=1, meshPart=None):
+    def ExportCGNS(self, f, overwrite=1, meshPart=None, groupElemsByType=False):
         unRegister = genObjUnRegister()
         if isinstance( meshPart, list ):
             meshPart = self.GetIDSource( meshPart, SMESH.ALL )
@@ -1889,7 +1897,7 @@ class Mesh:
             meshPart = meshPart.mesh
         elif not meshPart:
             meshPart = self.mesh
-        self.mesh.ExportCGNS(meshPart, f, overwrite)
+        self.mesh.ExportCGNS(meshPart, f, overwrite, groupElemsByType)
 
     ## Export the mesh in a file in GMF format.
     #  GMF files must have .mesh extension for the ASCII format and .meshb for
@@ -1912,9 +1920,14 @@ class Mesh:
     #  Export the mesh in a file in MED format
     #  allowing to overwrite the file if it exists or add the exported data to its contents
     #  @param f the file name
-    #  @param version MED format version (MED_V2_1 or MED_V2_2,
-    #                 the latter meaning any current version). The parameter is
-    #                 obsolete since MED_V2_1 is no longer supported.
+    #  @param version MED format version:
+    #         - MED_V2_1 is obsolete.
+    #         - MED_V2_2 means current version (kept for compatibility reasons)
+    #         - MED_LATEST means current version.
+    #         - MED_MINOR_x where x from 0 to 9 indicates the minor version of MED
+    #           to use for writing MED files, for backward compatibility :
+    #           for instance, with SALOME 8.4 use MED 3.2 (minor=2) instead of 3.3,
+    #           to allow the file to be read with SALOME 8.3.
     #  @param opt boolean parameter for creating/not creating
     #         the groups Group_On_All_Nodes, Group_On_All_Faces, ...
     #  @param overwrite boolean parameter for overwriting/not overwriting the file
@@ -1924,7 +1937,7 @@ class Mesh:
     #         - 3D in the rest cases.<br>
     #         If @a autoDimension is @c False, the space dimension is always 3.
     #  @ingroup l2_impexp
-    def ExportToMED(self, f, version=MED_V2_2, opt=0, overwrite=1, autoDimension=True):
+    def ExportToMED(self, f, version=MED_LATEST, opt=0, overwrite=1, autoDimension=True):
         self.mesh.ExportToMEDX(f, opt, version, overwrite, autoDimension)
 
     # Operations with groups:
@@ -2010,6 +2023,8 @@ class Mesh:
     #  @ingroup l2_grps_create
     def MakeGroupByIds(self, groupName, elementType, elemIDs):
         group = self.mesh.CreateGroup(elementType, groupName)
+        if isinstance( elemIDs, Mesh ):
+            elemIDs = elemIDs.GetMesh()
         if hasattr( elemIDs, "GetIDs" ):
             if hasattr( elemIDs, "SetMesh" ):
                 elemIDs.SetMesh( self.GetMesh() )
@@ -2687,9 +2702,14 @@ class Mesh:
 
     ## Return an element based on all given nodes.
     #  @ingroup l1_meshinfo
-    def FindElementByNodes(self,nodes):
+    def FindElementByNodes(self, nodes):
         return self.mesh.FindElementByNodes(nodes)
 
+    ## Return elements including all given nodes.
+    #  @ingroup l1_meshinfo
+    def GetElementsByNodes(self, nodes, elemType=SMESH.ALL):
+        return self.mesh.GetElementsByNodes( nodes, elemType )
+
     ## Return true if the given element is a polygon
     #  @ingroup l1_meshinfo
     def IsPoly(self, id):
@@ -3882,6 +3902,7 @@ class Mesh:
     #         - a GEOM point
     #  @return the list of created groups (SMESH_GroupBase) if MakeGroups=True, empty list otherwise
     #  @ingroup l2_modif_extrurev
+    #  @ref tui_extrusion example
     def ExtrusionSweepObjects(self, nodes, edges, faces, StepVector, NbOfSteps, MakeGroups=False,
                               scaleFactors=[], linearVariation=False, basePoint=[] ):
         unRegister = genObjUnRegister()
@@ -3922,6 +3943,7 @@ class Mesh:
     #  @param IsNodes is True if elements with given ids are nodes
     #  @return the list of created groups (SMESH_GroupBase) if MakeGroups=True, empty list otherwise
     #  @ingroup l2_modif_extrurev
+    #  @ref tui_extrusion example
     def ExtrusionSweep(self, IDsOfElements, StepVector, NbOfSteps, MakeGroups=False, IsNodes = False):
         n,e,f = [],[],[]
         if IsNodes: n = IDsOfElements
@@ -3948,6 +3970,7 @@ class Mesh:
     #  @return the list of created groups (SMESH_GroupBase) if \a MakeGroups=True,
     #          empty list otherwise.
     #  @ingroup l2_modif_extrurev
+    #  @ref tui_extrusion example
     def ExtrusionByNormal(self, Elements, StepSize, NbOfSteps,
                           ByAverageNormal=False, UseInputElemsOnly=True, MakeGroups=False, Dim = 2):
         unRegister = genObjUnRegister()
@@ -3977,6 +4000,7 @@ class Mesh:
     #  @param IsNodes is True if elements to extrude are nodes
     #  @return list of created groups (SMESH_GroupBase) if MakeGroups=True, empty list otherwise
     #  @ingroup l2_modif_extrurev
+    #  @ref tui_extrusion example
     def ExtrusionSweepObject(self, theObject, StepVector, NbOfSteps, MakeGroups=False, IsNodes=False):
         n,e,f = [],[],[]
         if IsNodes: n    = theObject
@@ -3993,6 +4017,7 @@ class Mesh:
     #  @param MakeGroups to generate new groups from existing ones
     #  @return list of created groups (SMESH_GroupBase) if MakeGroups=True, empty list otherwise
     #  @ingroup l2_modif_extrurev
+    #  @ref tui_extrusion example
     def ExtrusionSweepObject1D(self, theObject, StepVector, NbOfSteps, MakeGroups=False):
         return self.ExtrusionSweepObjects([],theObject,[], StepVector, NbOfSteps, MakeGroups)
 
@@ -4006,6 +4031,7 @@ class Mesh:
     #  @param MakeGroups forces the generation of new groups from existing ones
     #  @return list of created groups (SMESH_GroupBase) if MakeGroups=True, empty list otherwise
     #  @ingroup l2_modif_extrurev
+    #  @ref tui_extrusion example
     def ExtrusionSweepObject2D(self, theObject, StepVector, NbOfSteps, MakeGroups=False):
         return self.ExtrusionSweepObjects([],[],theObject, StepVector, NbOfSteps, MakeGroups)
 
@@ -4050,6 +4076,7 @@ class Mesh:
     #  @param MakeGroups forces the generation of new groups from existing ones
     #  @return list of created groups (SMESH_GroupBase) and SMESH::Extrusion_Error
     #  @ingroup l2_modif_extrurev
+    #  @ref tui_extrusion_along_path example
     def ExtrusionAlongPathObjects(self, Nodes, Edges, Faces, PathMesh, PathShape=None,
                                   NodeStart=1, HasAngles=False, Angles=[], LinearVariation=False,
                                   HasRefPoint=False, RefPoint=[0,0,0], MakeGroups=False):
@@ -4093,6 +4120,7 @@ class Mesh:
     #  @return list of created groups (SMESH_GroupBase) and SMESH::Extrusion_Error if MakeGroups=True,
     #          only SMESH::Extrusion_Error otherwise
     #  @ingroup l2_modif_extrurev
+    #  @ref tui_extrusion_along_path example
     def ExtrusionAlongPathX(self, Base, Path, NodeStart,
                             HasAngles=False, Angles=[], LinearVariation=False,
                             HasRefPoint=False, RefPoint=[0,0,0], MakeGroups=False,
@@ -4125,6 +4153,7 @@ class Mesh:
     #  @return list of created groups (SMESH_GroupBase) and SMESH::Extrusion_Error if MakeGroups=True,
     #          only SMESH::Extrusion_Error otherwise
     #  @ingroup l2_modif_extrurev
+    #  @ref tui_extrusion_along_path example
     def ExtrusionAlongPath(self, IDsOfElements, PathMesh, PathShape, NodeStart,
                            HasAngles=False, Angles=[], HasRefPoint=False, RefPoint=[],
                            MakeGroups=False, LinearVariation=False):
@@ -4155,6 +4184,7 @@ class Mesh:
     #  @return list of created groups (SMESH_GroupBase) and SMESH::Extrusion_Error if MakeGroups=True,
     #          only SMESH::Extrusion_Error otherwise
     #  @ingroup l2_modif_extrurev
+    #  @ref tui_extrusion_along_path example
     def ExtrusionAlongPathObject(self, theObject, PathMesh, PathShape, NodeStart,
                                  HasAngles=False, Angles=[], HasRefPoint=False, RefPoint=[],
                                  MakeGroups=False, LinearVariation=False):
@@ -4184,6 +4214,7 @@ class Mesh:
     #  @return list of created groups (SMESH_GroupBase) and SMESH::Extrusion_Error if MakeGroups=True,
     #          only SMESH::Extrusion_Error otherwise
     #  @ingroup l2_modif_extrurev
+    #  @ref tui_extrusion_along_path example
     def ExtrusionAlongPathObject1D(self, theObject, PathMesh, PathShape, NodeStart,
                                    HasAngles=False, Angles=[], HasRefPoint=False, RefPoint=[],
                                    MakeGroups=False, LinearVariation=False):
@@ -4213,6 +4244,7 @@ class Mesh:
     #  @return list of created groups (SMESH_GroupBase) and SMESH::Extrusion_Error if MakeGroups=True,
     #          only SMESH::Extrusion_Error otherwise
     #  @ingroup l2_modif_extrurev
+    #  @ref tui_extrusion_along_path example
     def ExtrusionAlongPathObject2D(self, theObject, PathMesh, PathShape, NodeStart,
                                    HasAngles=False, Angles=[], HasRefPoint=False, RefPoint=[],
                                    MakeGroups=False, LinearVariation=False):
@@ -5177,10 +5209,11 @@ omniORB.registerObjref(SMESH._objref_SMESH_Pattern._NP_RepositoryId, Pattern)
 ## Private class used to bind methods creating algorithms to the class Mesh
 #
 class algoCreator:
-    def __init__(self):
+    def __init__(self, method):
         self.mesh = None
         self.defaultAlgoType = ""
         self.algoTypeToClass = {}
+        self.method = method
 
     # Store a python class of algorithm
     def add(self, algoClass):
@@ -5194,25 +5227,48 @@ class algoCreator:
 
     # Create a copy of self and assign mesh to the copy
     def copy(self, mesh):
-        other = algoCreator()
+        other = algoCreator( self.method )
         other.defaultAlgoType = self.defaultAlgoType
-        other.algoTypeToClass  = self.algoTypeToClass
+        other.algoTypeToClass = self.algoTypeToClass
         other.mesh = mesh
         return other
 
     # Create an instance of algorithm
     def __call__(self,algo="",geom=0,*args):
-        algoType = self.defaultAlgoType
-        for arg in args + (algo,geom):
-            if isinstance( arg, geomBuilder.GEOM._objref_GEOM_Object ):
-                geom = arg
-            if isinstance( arg, str ) and arg:
+        algoType = ""
+        shape = 0
+        if isinstance( algo, str ):
+            algoType = algo
+        elif ( isinstance( algo, geomBuilder.GEOM._objref_GEOM_Object ) and \
+               not isinstance( geom, geomBuilder.GEOM._objref_GEOM_Object )):
+            shape = algo
+        elif algo:
+            args += (algo,)
+
+        if isinstance( geom, geomBuilder.GEOM._objref_GEOM_Object ):
+            shape = geom
+        elif not algoType and isinstance( geom, str ):
+            algoType = geom
+        elif geom:
+            args += (geom,)
+        for arg in args:
+            if isinstance( arg, geomBuilder.GEOM._objref_GEOM_Object ) and not shape:
+                shape = arg
+            elif isinstance( arg, str ) and not algoType:
                 algoType = arg
+            else:
+                import traceback, sys
+                msg = "Warning. Unexpected argument in mesh.%s() --->  %s" % ( self.method, arg )
+                sys.stderr.write( msg + '\n' )
+                tb = traceback.extract_stack(None,2)
+                traceback.print_list( [tb[0]] )
+        if not algoType:
+            algoType = self.defaultAlgoType
         if not algoType and self.algoTypeToClass:
             algoType = self.algoTypeToClass.keys()[0]
         if self.algoTypeToClass.has_key( algoType ):
             #print "Create algo",algoType
-            return self.algoTypeToClass[ algoType ]( self.mesh, geom )
+            return self.algoTypeToClass[ algoType ]( self.mesh, shape )
         raise RuntimeError, "No class found for algo type %s" % algoType
         return None
 
@@ -5294,7 +5350,7 @@ for pluginName in os.environ[ "SMESH_MeshersList" ].split( ":" ):
         if type( algo ).__name__ == 'classobj' and hasattr( algo, "meshMethod" ):
             #print "                     meshMethod:" , str(algo.meshMethod)
             if not hasattr( Mesh, algo.meshMethod ):
-                setattr( Mesh, algo.meshMethod, algoCreator()
+                setattr( Mesh, algo.meshMethod, algoCreator( algo.meshMethod ))
                 pass
             getattr( Mesh, algo.meshMethod ).add( algo )
             pass
index 4132fa9a31887dda89af12777b08218ea7e5a4a2..8a252507cbe8c7f57b70fd8a1d46b69315c7cff3 100644 (file)
@@ -98,6 +98,7 @@ SET(_swig_SCRIPTS
 
 SWIG_ADD_MODULE(libSMESH_Swig python ${SMESH_Swig_SOURCES})
 SWIG_LINK_LIBRARIES(libSMESH_Swig ${_link_LIBRARIES})
+SWIG_CHECK_GENERATION(libSMESH_Swig)
 IF(WIN32)
   SET_TARGET_PROPERTIES(_libSMESH_Swig PROPERTIES DEBUG_OUTPUT_NAME _libSMESH_Swig_d)
 ENDIF(WIN32)
index 231dd33b5eb7a132013d734008dc5fdcad81441f..0a111304ec6e22945118c471f05f8211e9701878 100644 (file)
@@ -49,6 +49,7 @@
 #include <SalomeApp_Application.h>
 #include <LightApp_SelectionMgr.h>
 #include <SVTK_RenderWindowInteractor.h>
+#include <VTKViewer_Algorithm.h>
 
 // OCCT includes
 #include <TopAbs.hxx>
 #include CORBA_SERVER_HEADER(SMESH_Gen)
 #include CORBA_SERVER_HEADER(SMESH_Hypothesis)
 
+// VTK includes
+#include <vtkActorCollection.h>
+#include <vtkRenderer.h>
+
 static CORBA::ORB_var anORB;
 
 namespace
@@ -892,17 +897,18 @@ public:
   {}
   virtual void Execute()
   {
-    SMESHGUI* aSMESHGUI = SMESHGUI::GetSMESHGUI();
-    if( !aSMESHGUI ) 
-      return;
     
-    LightApp_SelectionMgr* selMgr = SMESH::GetSelectionMgr( aSMESHGUI );
+    LightApp_SelectionMgr* selMgr = 0;
+    SalomeApp_Application* anApp = dynamic_cast<SalomeApp_Application*>( SUIT_Session::session()->activeApplication() );
+    if( anApp )
+      selMgr = dynamic_cast<LightApp_SelectionMgr*>( anApp->selectionMgr() );
+
     if( !selMgr )
       return;
     
     selMgr->clearFilters();
 
-    SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( aSMESHGUI );
+    SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow();
     if(!aViewWindow)
       return;
 
@@ -960,26 +966,106 @@ void SMESH_Swig::select( const char* id, int id1, bool append ) {
 class TGetSelectionModeEvent : public SALOME_Event
 {
 public:
-  typedef int TResult;
+  typedef SelectionMode TResult;
   TResult myResult;
-  TGetSelectionModeEvent() : myResult( -1 ) {}
+  TGetSelectionModeEvent() : myResult( Undefined ) {}
   virtual void Execute()
   {
-    SMESHGUI* aSMESHGUI = SMESHGUI::GetSMESHGUI();
-    if( !aSMESHGUI ) 
-      return;
-
-    SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( aSMESHGUI );
+    SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( );
     if(!aViewWindow)
       return;
     
-    myResult = aViewWindow->SelectionMode();
+    myResult = (SelectionMode) aViewWindow->SelectionMode();
   }
 };
 
 /*!
   \brief Get selection mode of the active VTK View window.
 */
-int SMESH_Swig::getSelectionMode() {
+SelectionMode SMESH_Swig::getSelectionMode() {
   return ProcessEvent( new TGetSelectionModeEvent() );
 }
+
+
+/*!
+ * Event to set selection mode
+*/
+class TSetSelectionModeEvent : public SALOME_Event
+{
+  SelectionMode mySelectionMode;
+
+public:
+
+  TSetSelectionModeEvent(const SelectionMode selectionMode) :
+    mySelectionMode(selectionMode) 
+  {}
+
+  virtual void Execute()
+  {
+    SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow();
+    if(!aViewWindow)
+      return;
+
+    Selection_Mode prevMode = aViewWindow->SelectionMode();
+    bool changePointRepresentation = ( prevMode == NodeSelection && mySelectionMode != Node ) ||
+      (prevMode != NodeSelection && mySelectionMode == Node);
+      
+    if( changePointRepresentation ) {
+      vtkRenderer *aRenderer = aViewWindow->getRenderer();
+      VTK::ActorCollectionCopy aCopy(aRenderer->GetActors());
+      vtkActorCollection *aCollection = aCopy.GetActors();
+      aCollection->InitTraversal();
+      while(vtkActor *anAct = aCollection->GetNextActor()){
+       if(SMESH_Actor *anActor = dynamic_cast<SMESH_Actor*>(anAct)){
+         if(anActor->GetVisibility()){
+           anActor->SetPointRepresentation(mySelectionMode == Node);
+         }
+       }
+      }
+    }
+    aViewWindow->SetSelectionMode(mySelectionMode);
+  }
+};
+
+void SMESH_Swig::setSelectionMode(SelectionMode selectionMode){
+  ProcessVoidEvent( new TSetSelectionModeEvent( selectionMode ) ); 
+}
+
+class TGetSelectedEvent : public SALOME_Event
+{
+public:
+  typedef std::vector<int> TResult;
+  TResult myResult;
+  const char* myId;
+  
+  TGetSelectedEvent( const char* id) : 
+    myResult( std::vector<int>() ),
+    myId(id)
+  {}
+  
+  virtual void Execute()
+  {
+    SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow();
+    if( !aViewWindow )
+      return;
+
+    SVTK_Selector* aSelector  = aViewWindow->GetSelector();    
+    if( !aSelector )
+      return;
+
+    SMESH_Actor* anActor = SMESH::FindActorByEntry( myId );
+    
+    if ( !anActor || !anActor->hasIO() )
+      return;
+
+    TColStd_IndexedMapOfInteger aMapIndex;
+    aSelector->GetIndex(anActor->getIO(),aMapIndex);
+
+    for( int i = 1; i <= aMapIndex.Extent(); i++ )
+      myResult.push_back( aMapIndex( i ) );
+  }
+};
+
+std::vector<int> SMESH_Swig::getSelected( const char* Mesh_Entry ) {
+  return ProcessEvent( new TGetSelectedEvent(Mesh_Entry) );
+}
index 86682ff5b79baa3465050fe6d74d9862fefae85e..5522e95a219589618616afe3caf3ba781a8f6f43 100644 (file)
@@ -45,8 +45,9 @@
 
 #include <SVTK_Selection.h>
 
-enum
+typedef enum
   {
+    Undefined  = -1,
     Node       = NodeSelection,
     Cell       = CellSelection,
     EdgeOfCell = EdgeOfCellSelection,
@@ -56,7 +57,7 @@ enum
     Actor      = ActorSelection,
     Elem0D     = Elem0DSelection,
     Ball       = BallSelection
-  };
+  } SelectionMode;
 
 typedef struct
 {
@@ -128,8 +129,11 @@ public:
   actorAspect                GetActorAspect(const char* Mesh_Entry, int viewId = 0 );
   void                       SetActorAspect( const actorAspect& actorPres, const char* Mesh_Entry, int viewId = 0  );
 
+  void setSelectionMode( SelectionMode selectionMode );
+  std::vector<int> getSelected( const char* Mesh_Entry );
+
   // --------------------- for the test purposes -----------------------
-  int  getSelectionMode();
+  SelectionMode getSelectionMode();
   void select( const char *id, std::vector<int> ids, bool append = false );
   void select( const char *id, int id1, bool append = false );
 
index ac732d4672e8f64d8626a71b65cd20528cbd8f98..339668801d7b8402ef44207d911f9e18c723c593 100644 (file)
@@ -55,9 +55,10 @@ namespace std {
 
 
 /* Selection mode enumeration (corresponds to constants from the SALOME_Selection.h) */
-enum
+enum SelectionMode
   {
-    Node,
+    Undefined = -1,
+    Node = 0,
     Cell,
     EdgeOfCell,
     Edge,
@@ -131,8 +132,11 @@ class SMESH_Swig
   actorAspect GetActorAspect(const char* Mesh_Entry, int viewId = 0 );
   void SetActorAspect( const actorAspect& actorPres, const char* Mesh_Entry, int viewId = 0 );
 
+  void setSelectionMode( SelectionMode selectionMode);
+  std::vector<int> getSelected( const char* Mesh_Entry );
+
   // --------------------- for the test purposes -----------------------
-  int  getSelectionMode();
+  SelectionMode  getSelectionMode();
   void select( const char *id, std::vector<int> ids, bool append = false );
   void select( const char *id, int id1, bool append = false );
 
index f55687ca3ead5a1d620edcf7fa12213d71735f36..6c0fcb6a59813343ab58eff1079e34bc4d36727f 100644 (file)
@@ -792,7 +792,7 @@ std::ostream & StdMeshers_CartesianParameters3D::SaveTo(std::ostream & save)
 
 //=======================================================================
 //function : LoadFrom
-//purpose  : resore my parameters from a stream
+//purpose  : restore my parameters from a stream
 //=======================================================================
 
 std::istream & StdMeshers_CartesianParameters3D::LoadFrom(std::istream & load)
index aebd779eea189c77019b1ac01a7b7bc6ea636687..002f209619b9847b091359a6cedebcc15757e721 100644 (file)
@@ -36,7 +36,6 @@
 
 #include <utilities.h>
 #include <Utils_ExceptHandlers.hxx>
-#include <Basics_OCCTVersion.hxx>
 
 #include <GEOMUtils.hxx>
 
@@ -1371,11 +1370,7 @@ namespace
     }
     if ( surf->IsKind( STANDARD_TYPE(Geom_BSplineSurface )) ||
          surf->IsKind( STANDARD_TYPE(Geom_BezierSurface )))
-#if OCC_VERSION_MAJOR < 7
-      if ( !noSafeTShapes.insert((const Standard_Transient*) _face.TShape() ).second )
-#else
       if ( !noSafeTShapes.insert( _face.TShape().get() ).second )
-#endif
         isSafe = false;
 
     double f, l;
@@ -1415,11 +1410,7 @@ namespace
             edgeIsSafe = false;
         }
       }
-#if OCC_VERSION_MAJOR < 7
-      if ( !edgeIsSafe && !noSafeTShapes.insert((const Standard_Transient*) e.TShape() ).second )
-#else
       if ( !edgeIsSafe && !noSafeTShapes.insert( e.TShape().get() ).second )
-#endif
         isSafe = false;
     }
     return isSafe;
@@ -2924,7 +2915,7 @@ namespace
       proj.Perform( testPnt );
       if ( proj.IsDone() && proj.NbPoints() > 0 )       
       {
-        Quantity_Parameter u,v;
+        Standard_Real u,v;
         proj.LowerDistanceParameters( u,v );
 
         if ( proj.LowerDistance() <= 0.1 * _grid->_tol )
index f1f26aebf554d577f7bf27457f24cef0c0bb8e98..aeef4e1ef465976cbb1f543d415ea3311f66b796 100644 (file)
 #include <math_GaussSingleIntegration.hxx>
 #include <utilities.h>
 
-#if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
-#define NO_CAS_CATCH
-#endif
-
 #include <Standard_Failure.hxx>
 #include <Expr_NamedUnknown.hxx>
-
-#ifdef NO_CAS_CATCH
 #include <Standard_ErrorHandler.hxx>
-#endif
 
 using namespace std;
 
@@ -60,12 +53,9 @@ bool Function::value( const double, double& f ) const
   bool ok = true;
   if (myConv == 0) {
     try {
-#ifdef NO_CAS_CATCH
       OCC_CATCH_SIGNALS;
-#endif
       f = pow( 10., f );
     } catch(Standard_Failure) {
-      Handle(Standard_Failure) aFail = Standard_Failure::Caught();
       f = 0.0;
       ok = false;
     }
@@ -192,13 +182,10 @@ FunctionExpr::FunctionExpr( const char* str, const int conv )
 {
   bool ok = true;
   try {
-#ifdef NO_CAS_CATCH
     OCC_CATCH_SIGNALS;
-#endif
     myExpr = ExprIntrp_GenExp::Create();
     myExpr->Process( ( Standard_CString )str );
   } catch(Standard_Failure) {
-    Handle(Standard_Failure) aFail = Standard_Failure::Caught();
     ok = false;
   }
 
@@ -228,12 +215,9 @@ bool FunctionExpr::value( const double t, double& f ) const
   ( ( TColStd_Array1OfReal& )myValues ).ChangeValue( 1 ) = t;
   bool ok = true;
   try {
-#ifdef NO_CAS_CATCH
     OCC_CATCH_SIGNALS;
-#endif
     f = myExpr->Expression()->Evaluate( myVars, myValues );
   } catch(Standard_Failure) {
-    Handle(Standard_Failure) aFail = Standard_Failure::Caught();
     f = 0.0;
     ok = false;
   }
@@ -246,9 +230,7 @@ double FunctionExpr::integral( const double a, const double b ) const
 {
   double res = 0.0;
   try {
-#ifdef NO_CAS_CATCH
     OCC_CATCH_SIGNALS;
-#endif
     math_GaussSingleIntegration _int
       ( *static_cast<math_Function*>( const_cast<FunctionExpr*> (this) ), a, b, 20 );
     if( _int.IsDone() )
index 9f5929e3681a9a4bcb5b2957c64bf752ac1781f6..b0d36a59ccb5bd25c9f7aa58a6a9006e4b6e2605 100644 (file)
@@ -88,13 +88,13 @@ StdMeshers_FaceSide::StdMeshers_FaceSide(const TopoDS_Face&   theFace,
  */
 //================================================================================
 
-StdMeshers_FaceSide::StdMeshers_FaceSide(const TopoDS_Face&      theFace,
-                                         std::list<TopoDS_Edge>& theEdges,
-                                         SMESH_Mesh*             theMesh,
-                                         const bool              theIsForward,
-                                         const bool              theIgnoreMediumNodes,
-                                         SMESH_MesherHelper*     theFaceHelper,
-                                         SMESH_ProxyMesh::Ptr    theProxyMesh)
+StdMeshers_FaceSide::StdMeshers_FaceSide(const TopoDS_Face&            theFace,
+                                         const std::list<TopoDS_Edge>& theEdges,
+                                         SMESH_Mesh*                   theMesh,
+                                         const bool                    theIsForward,
+                                         const bool                    theIgnoreMediumNodes,
+                                         SMESH_MesherHelper*           theFaceHelper,
+                                         SMESH_ProxyMesh::Ptr          theProxyMesh)
 {
   int nbEdges = theEdges.size();
   myEdge.resize      ( nbEdges );
@@ -125,7 +125,7 @@ StdMeshers_FaceSide::StdMeshers_FaceSide(const TopoDS_Face&      theFace,
   SMESHDS_Mesh* meshDS = myProxyMesh->GetMeshDS();
 
   int nbDegen = 0;
-  std::list<TopoDS_Edge>::iterator edge = theEdges.begin();
+  std::list<TopoDS_Edge>::const_iterator edge = theEdges.begin();
   for ( int index = 0; edge != theEdges.end(); ++index, ++edge )
   {
     int i = theIsForward ? index : nbEdges-index-1;
@@ -166,6 +166,14 @@ StdMeshers_FaceSide::StdMeshers_FaceSide(const TopoDS_Face&      theFace,
         myC3dAdaptor[i].Load( C3d, 0, 0.5 * BRep_Tool::Tolerance( V ));
       }
     }
+    else if ( myEdgeLength[i] > DBL_MIN )
+    {
+      Handle(Geom_Curve) C3d = BRep_Tool::Curve(myEdge[i],myFirst[i], myLast[i] );
+      myC3dAdaptor[i].Load( C3d, myFirst[i], myLast[i] );
+      if ( myEdge[i].Orientation() == TopAbs_REVERSED )
+        std::swap( myFirst[i], myLast[i] );
+    }
+
     // reverse a proxy sub-mesh
     if ( !theIsForward )
       reverseProxySubmesh( myEdge[i] );
@@ -1243,7 +1251,7 @@ gp_Pnt StdMeshers_FaceSide::Value3d(double U) const
   // check parametrization of curve
   if( !myIsUniform[i] )
   {
-    double aLen3dU = r * myEdgeLength[i] * ( myFirst[i]>myLast[i] ? -1. : 1.);
+    double aLen3dU = r * myEdgeLength[i] * ( myFirst[i] > myLast[i] ? -1. : 1. );
     GCPnts_AbscissaPoint AbPnt
       ( const_cast<GeomAdaptor_Curve&>( myC3dAdaptor[i]), aLen3dU, myFirst[i] );
     if( AbPnt.IsDone() ) {
index 6759f50a920ce7ccbd08c67e1b46c9a9b0c239f5..1964638fea6b65467a415bc6fff2a38d092b529b 100644 (file)
@@ -82,13 +82,13 @@ public:
   /*!
    * \brief Wrap several edges. Edges must be properly ordered and oriented.
    */
-  StdMeshers_FaceSide(const TopoDS_Face&      theFace,
-                      std::list<TopoDS_Edge>& theEdges,
-                      SMESH_Mesh*             theMesh,
-                      const bool              theIsForward,
-                      const bool              theIgnoreMediumNodes,
-                      SMESH_MesherHelper*     theFaceHelper = NULL,
-                      SMESH_ProxyMesh::Ptr    theProxyMesh = SMESH_ProxyMesh::Ptr());
+  StdMeshers_FaceSide(const TopoDS_Face&            theFace,
+                      const std::list<TopoDS_Edge>& theEdges,
+                      SMESH_Mesh*                   theMesh,
+                      const bool                    theIsForward,
+                      const bool                    theIgnoreMediumNodes,
+                      SMESH_MesherHelper*           theFaceHelper = NULL,
+                      SMESH_ProxyMesh::Ptr          theProxyMesh = SMESH_ProxyMesh::Ptr());
   /*!
    * \brief Simulate a side from a vertex using data from other FaceSide
    */
@@ -120,13 +120,13 @@ public:
   { return StdMeshers_FaceSidePtr
       ( new StdMeshers_FaceSide( Face,Edge,Mesh,IsForward,IgnoreMediumNodes,FaceHelper,ProxyMesh ));
   }
-  static StdMeshers_FaceSidePtr New (const TopoDS_Face&      Face,
-                                     std::list<TopoDS_Edge>& Edges,
-                                     SMESH_Mesh*             Mesh,
-                                     const bool              IsForward,
-                                     const bool              IgnoreMediumNodes,
-                                     SMESH_MesherHelper*     FaceHelper = NULL,
-                                     SMESH_ProxyMesh::Ptr    ProxyMesh = SMESH_ProxyMesh::Ptr())
+  static StdMeshers_FaceSidePtr New (const TopoDS_Face&            Face,
+                                     const std::list<TopoDS_Edge>& Edges,
+                                     SMESH_Mesh*                   Mesh,
+                                     const bool                    IsForward,
+                                     const bool                    IgnoreMediumNodes,
+                                     SMESH_MesherHelper*           FaceHelper = NULL,
+                                     SMESH_ProxyMesh::Ptr          ProxyMesh = SMESH_ProxyMesh::Ptr())
   { return StdMeshers_FaceSidePtr
       ( new StdMeshers_FaceSide( Face,Edges,Mesh,IsForward,IgnoreMediumNodes,FaceHelper,ProxyMesh ));
   }
@@ -141,9 +141,11 @@ public:
       ( new StdMeshers_FaceSide( Side,Node,Pnt2d1,Pnt2d2,C2d,UFirst,ULast ));
   }
   static StdMeshers_FaceSidePtr New (UVPtStructVec&     theSideNodes,
-                                     const TopoDS_Face& theFace = TopoDS_Face())
+                                     const TopoDS_Face& theFace = TopoDS_Face(),
+                                     const TopoDS_Edge& theEdge = TopoDS_Edge(),
+                                     SMESH_Mesh*        theMesh = 0)
   {
-    return StdMeshers_FaceSidePtr( new StdMeshers_FaceSide( theSideNodes, theFace ));
+    return StdMeshers_FaceSidePtr( new StdMeshers_FaceSide( theSideNodes, theFace, theEdge, theMesh ));
   }
 
   /*!
index 3673cdba94bce03dba713c5b3dd18719ca512069..8b50468b7c37625f48e238987b1709f2de9bc491 100644 (file)
@@ -54,6 +54,10 @@ public:
   virtual bool Evaluate(SMESH_Mesh & aMesh, const TopoDS_Shape & aShape,
                         MapShapeNbElems& aResMap);
 
+  virtual bool IsApplicableToShape(const TopoDS_Shape & shape, bool toCheckAll) const
+  {
+    return IsApplicable( shape, toCheckAll );
+  }
   static bool IsApplicable(const TopoDS_Shape & aShape, bool toCheckAll);
 
  protected:
index 0d4a369e881b5970018fe4e2d679ea76caefd457..8cc97b6e017243dd4296e504c46d93fdd823b610 100644 (file)
@@ -34,6 +34,7 @@
 #include "SMESHDS_Group.hxx"
 #include "SMESHDS_Mesh.hxx"
 #include "SMESH_Comment.hxx"
+#include "SMESH_ControlsDef.hxx"
 #include "SMESH_Gen.hxx"
 #include "SMESH_Group.hxx"
 #include "SMESH_Mesh.hxx"
@@ -187,8 +188,8 @@ bool StdMeshers_Import_1D2D::Compute(SMESH_Mesh & theMesh, const TopoDS_Shape &
   SMESHDS_Mesh* tgtMesh = theMesh.GetMeshDS();
 
   const TopoDS_Face& geomFace = TopoDS::Face( theShape );
-  const double faceTol = helper.MaxTolerance( geomFace );
-  const int shapeID = tgtMesh->ShapeToIndex( geomFace );
+  const double  faceTol = helper.MaxTolerance( geomFace );
+  const int     shapeID = tgtMesh->ShapeToIndex( geomFace );
   const bool toCheckOri = (helper.NbAncestors( geomFace, theMesh, TopAbs_SOLID ) == 1 );
 
 
@@ -269,12 +270,25 @@ bool StdMeshers_Import_1D2D::Compute(SMESH_Mesh & theMesh, const TopoDS_Shape &
   map<TLink, int>::iterator link2Nb;
   double minGroupTol = Precision::Infinite();
 
+  SMESH::Controls::ElementsOnShape onEdgeClassifier;
+  if ( helper.HasSeam() )
+  {
+    TopoDS_Compound edgesCompound;
+    BRep_Builder    builder;
+    builder.MakeCompound( edgesCompound );
+    for ( size_t iE = 0; iE < edges.size(); ++iE )
+      builder.Add( edgesCompound, edges[ iE ]);
+    onEdgeClassifier.SetShape( edgesCompound, SMDSAbs_Node );
+  }
+
   // =========================
   // Import faces from groups
   // =========================
 
   StdMeshers_Import_1D::TNodeNodeMap* n2n;
   StdMeshers_Import_1D::TElemElemMap* e2e;
+  StdMeshers_Import_1D::TNodeNodeMap::iterator n2nIt;
+  pair< StdMeshers_Import_1D::TNodeNodeMap::iterator, bool > it_isnew;
   vector<TopAbs_State>         nodeState;
   vector<const SMDS_MeshNode*> newNodes; // of a face
   set   <const SMDS_MeshNode*> bndNodes; // nodes classified ON
@@ -297,8 +311,8 @@ bool StdMeshers_Import_1D2D::Compute(SMESH_Mesh & theMesh, const TopoDS_Shape &
     //                             S.VResolution( 0.1 * groupTol ));
     const double clsfTol = BRep_Tool::Tolerance( geomFace );
 
-    StdMeshers_Import_1D::TNodeNodeMap::iterator n2nIt;
-    pair< StdMeshers_Import_1D::TNodeNodeMap::iterator, bool > it_isnew;
+    if ( helper.HasSeam() )
+      onEdgeClassifier.SetMesh( srcMesh->GetMeshDS() );
 
     SMDS_ElemIteratorPtr srcElems = srcGroup->GetElements();
     while ( srcElems->more() ) // loop on group contents
@@ -356,11 +370,21 @@ bool StdMeshers_Import_1D2D::Compute(SMESH_Mesh & theMesh, const TopoDS_Shape &
           gp_XY uv( Precision::Infinite(), 0 );
           isOut = ( !helper.CheckNodeUV( geomFace, *node, uv, groupTol, /*force=*/true ) ||
                     bndBox2d.IsOut( uv ));
+          //int iCoo;
           if ( !isOut && !isIn ) // classify
           {
             classifier.Perform( geomFace, uv, clsfTol );
             nodeState[i] = classifier.State();
             isOut = ( nodeState[i] == TopAbs_OUT );
+            if ( isOut && helper.IsOnSeam( uv ) && onEdgeClassifier.IsSatisfy( (*node)->GetID() ))
+            {
+              // uv.SetCoord( iCoo, helper.GetOtherParam( uv.Coord( iCoo )));
+              // classifier.Perform( geomFace, uv, clsfTol );
+              // nodeState[i] = classifier.State();
+              // isOut = ( nodeState[i] == TopAbs_OUT );
+              nodeState[i] = TopAbs_ON;
+              isOut = false;
+            }
           }
           if ( !isOut ) // create a new node
           {
@@ -374,13 +398,14 @@ bool StdMeshers_Import_1D2D::Compute(SMESH_Mesh & theMesh, const TopoDS_Shape &
             }
             if ( nodeState[i] == TopAbs_ON )
               bndNodes.insert( *node );
-            else
+            else if ( nodeState[i] != TopAbs_UNKNOWN )
               isNodeIn[ newNode->GetID() ] = isIn = true;
           }
         }
         if ( !(newNodes[i] = newNode ) || isOut )
           break;
-      }
+
+      } // loop on face nodes
 
       if ( !newNodes.back() )
         continue; // not all nodes of the face lie on theShape
@@ -411,7 +436,7 @@ bool StdMeshers_Import_1D2D::Compute(SMESH_Mesh & theMesh, const TopoDS_Shape &
           proj.Perform( gc );
           if ( !proj.IsDone() || proj.NbPoints() < 1 )
             continue;
-          Quantity_Parameter U,V;
+          Standard_Real U,V;
           proj.LowerDistanceParameters(U,V);
           gp_XY uv( U,V );
           classifier.Perform( geomFace, uv, clsfTol );
@@ -491,23 +516,32 @@ bool StdMeshers_Import_1D2D::Compute(SMESH_Mesh & theMesh, const TopoDS_Shape &
           medium = newNodes[i+nbCorners];
         link2Nb = linkCount.insert( make_pair( TLink( n1, n2, medium ), 0)).first;
         ++link2Nb->second;
-        // if ( link2Nb->second == 1 )
-        // {
-        //   // measure link length
-        //   double len2 = SMESH_TNodeXYZ( n1 ).SquareDistance( n2 );
-        //   if ( len2 < minGroupTol )
-        //     minGroupTol = len2;
-        // }
       }
-    }
+    } // loop on group contents
+
     // Remove OUT nodes from n2n map
     for ( n2nIt = n2n->begin(); n2nIt != n2n->end(); )
       if ( !n2nIt->second )
         n2n->erase( n2nIt++ );
       else
         ++n2nIt;
-  }
 
+  } // loop on src groups
+
+  // remove free nodes created on EDGEs
+  {
+    set<const SMDS_MeshNode*>::iterator node = bndNodes.begin();
+    for ( ; node != bndNodes.end(); ++node )
+    {
+      n2nIt = n2n->find( *node );
+      const SMDS_MeshNode* newNode = n2nIt->second;
+      if ( newNode && newNode->NbInverseElements() == 0 )
+      {
+        tgtMesh->RemoveFreeNode( newNode, 0, false );
+        n2n->erase( n2nIt );
+      }
+    }
+  }
 
   // ==========================================================
   // Put nodes on geom edges and create edges on them;
index 2ff7274fc2b0827483a13c14ec9adc555f7477c7..98dac7e8439a66d993600907f5661b1005430dd6 100644 (file)
 #include <TopExp.hxx>
 #include <TopTools_IndexedMapOfShape.hxx>
 
-#if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
-#define NO_CAS_CATCH
-#endif
-
 #include <Standard_Failure.hxx>
-
-#ifdef NO_CAS_CATCH
 #include <Standard_ErrorHandler.hxx>
-#endif
 
 #include <Basics_Utils.hxx>
 
@@ -238,13 +231,10 @@ void StdMeshers_NumberOfSegments::SetTableFunction(const vector<double>& table)
     if( _convMode==0 )
     {
       try {
-#ifdef NO_CAS_CATCH
         OCC_CATCH_SIGNALS;
-#endif
         val = pow( 10.0, val );
       }
       catch(Standard_Failure) {
-        Handle(Standard_Failure) aFail = Standard_Failure::Caught();
         throw SALOME_Exception( LOCALIZED( "invalid value"));
         return;
       }
@@ -335,13 +325,10 @@ bool process( const TCollection_AsciiString& str, int convMode,
   bool parsed_ok = true;
   Handle( ExprIntrp_GenExp ) myExpr;
   try {
-#ifdef NO_CAS_CATCH
     OCC_CATCH_SIGNALS;
-#endif
     myExpr = ExprIntrp_GenExp::Create();
     myExpr->Process( str.ToCString() );
   } catch(Standard_Failure) {
-    Handle(Standard_Failure) aFail = Standard_Failure::Caught();
     parsed_ok = false;
   }
 
index a7dae02832c902abde6f7a23301d04c86bc7c1a8..4dd948be3fb334511a0ec02dc5ccc5890635eb59 100644 (file)
@@ -51,6 +51,7 @@
 #include <Geom2d_Line.hxx>
 #include <GeomLib_IsPlanarSurface.hxx>
 #include <Geom_Curve.hxx>
+#include <Standard_ErrorHandler.hxx>
 #include <TopExp.hxx>
 #include <TopExp_Explorer.hxx>
 #include <TopTools_ListIteratorOfListOfShape.hxx>
@@ -110,6 +111,7 @@ namespace {
         algo->myProxyMesh.reset( new SMESH_ProxyMesh( *helper->GetMesh() ));
 
       algo->myQuadList.clear();
+      algo->myHelper = 0;
 
       if ( helper )
         algo->_quadraticMesh = helper->GetIsQuadratic();
@@ -528,6 +530,27 @@ namespace {
     return nbSides;
   }
 
+  //================================================================================
+  /*!
+   * \brief Set/get wire index to FaceQuadStruct
+   */
+  //================================================================================
+
+  void setWireIndex( TFaceQuadStructPtr& quad, int iWire )
+  {
+    quad->iSize = iWire;
+  }
+  int getWireIndex( const TFaceQuadStructPtr& quad )
+  {
+    return quad->iSize;
+  }
+
+  //================================================================================
+  /*!
+   * \brief Print Python commands adding given points to a mesh
+   */
+  //================================================================================
+
   void pointsToPython(const std::vector<gp_XYZ>& p)
   {
 #ifdef _DEBUG_
@@ -558,6 +581,7 @@ StdMeshers_Prism_3D::StdMeshers_Prism_3D(int hypId, int studyId, SMESH_Gen* gen)
 
   //myProjectTriangles       = false;
   mySetErrorToSM           = true;  // to pass an error to a sub-mesh of a current solid or not
+  myPrevBottomSM           = 0;     // last treated bottom sub-mesh with a suitable algorithm
 }
 
 //================================================================================
@@ -580,39 +604,6 @@ bool StdMeshers_Prism_3D::CheckHypothesis(SMESH_Mesh&                          a
                                           const TopoDS_Shape&                  aShape,
                                           SMESH_Hypothesis::Hypothesis_Status& aStatus)
 {
-  // Check shape geometry
-/*  PAL16229
-  aStatus = SMESH_Hypothesis::HYP_BAD_GEOMETRY;
-
-  // find not quadrangle faces
-  list< TopoDS_Shape > notQuadFaces;
-  int nbEdge, nbWire, nbFace = 0;
-  TopExp_Explorer exp( aShape, TopAbs_FACE );
-  for ( ; exp.More(); exp.Next() ) {
-    ++nbFace;
-    const TopoDS_Shape& face = exp.Current();
-    nbEdge = NSProjUtils::Count( face, TopAbs_EDGE, 0 );
-    nbWire = NSProjUtils::Count( face, TopAbs_WIRE, 0 );
-    if (  nbEdge!= 4 || nbWire!= 1 ) {
-      if ( !notQuadFaces.empty() ) {
-        if ( NSProjUtils::Count( notQuadFaces.back(), TopAbs_EDGE, 0 ) != nbEdge ||
-             NSProjUtils::Count( notQuadFaces.back(), TopAbs_WIRE, 0 ) != nbWire )
-          RETURN_BAD_RESULT("Different not quad faces");
-      }
-      notQuadFaces.push_back( face );
-    }
-  }
-  if ( !notQuadFaces.empty() )
-  {
-    if ( notQuadFaces.size() != 2 )
-      RETURN_BAD_RESULT("Bad nb not quad faces: " << notQuadFaces.size());
-
-    // check total nb faces
-    nbEdge = NSProjUtils::Count( notQuadFaces.back(), TopAbs_EDGE, 0 );
-    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;
@@ -627,6 +618,7 @@ bool StdMeshers_Prism_3D::Compute(SMESH_Mesh& theMesh, const TopoDS_Shape& theSh
 {
   SMESH_MesherHelper helper( theMesh );
   myHelper = &helper;
+  myPrevBottomSM = 0;
 
   int nbSolids = helper.Count( theShape, TopAbs_SOLID, /*skipSame=*/false );
   if ( nbSolids < 1 )
@@ -943,7 +935,7 @@ bool StdMeshers_Prism_3D::getWallFaces( Prism_3D::TPrismTopo & thePrism,
   list< TopoDS_Edge >::iterator edge = thePrism.myBottomEdges.begin();
   std::list< int >::iterator     nbE = thePrism.myNbEdgesInWires.begin();
   std::list< int > nbQuadsPerWire;
-  int iE = 0;
+  int iE = 0, iWire = 0;
   while ( edge != thePrism.myBottomEdges.end() )
   {
     ++iE;
@@ -977,7 +969,10 @@ bool StdMeshers_Prism_3D::getWallFaces( Prism_3D::TPrismTopo & thePrism,
                 return toSM( error(TCom("Composite 'horizontal' edges are not supported")));
           }
           if ( faceMap.Add( face ))
+          {
+            setWireIndex( quadList.back(), iWire ); // for use in makeQuadsForOutInProjection()
             thePrism.myWallQuads.push_back( quadList );
+          }
           break;
         }
       }
@@ -995,6 +990,7 @@ bool StdMeshers_Prism_3D::getWallFaces( Prism_3D::TPrismTopo & thePrism,
     if ( iE == *nbE )
     {
       iE = 0;
+      ++iWire;
       ++nbE;
       int nbQuadPrev = std::accumulate( nbQuadsPerWire.begin(), nbQuadsPerWire.end(), 0 );
       nbQuadsPerWire.push_back( thePrism.myWallQuads.size() - nbQuadPrev );
@@ -1129,13 +1125,8 @@ bool StdMeshers_Prism_3D::compute(const Prism_3D::TPrismTopo& thePrism)
     return toSM( error( SMESH_ComputeError::New(COMPERR_CANCELED)));
 
   // Assure the bottom is meshed
-  SMESH_subMesh * botSM = myHelper->GetMesh()->GetSubMesh( thePrism.myBottom );
-  if (( botSM->IsEmpty() ) &&
-      ( ! botSM->GetAlgo() ||
-        ! _gen->Compute( *botSM->GetFather(), botSM->GetSubShape(), /*shapeOnly=*/true )))
-    return error( COMPERR_BAD_INPUT_MESH,
-                  TCom( "No mesher defined to compute the base face #")
-                  << shapeID( thePrism.myBottom ));
+  if ( !computeBase( thePrism ))
+    return false;
 
   // Make all side FACEs of thePrism meshed with quads
   if ( !computeWalls( thePrism ))
@@ -1160,7 +1151,8 @@ bool StdMeshers_Prism_3D::compute(const Prism_3D::TPrismTopo& thePrism)
   // else if ( !trsf.empty() )
   //   bottomToTopTrsf = trsf.back();
 
-  // To compute coordinates of a node inside a block, it is necessary to know
+  // To compute coordinates of a node inside a block using "block approach",
+  // it is necessary to know
   // 1. normalized parameters of the node by which
   // 2. coordinates of node projections on all block sub-shapes are computed
 
@@ -1173,7 +1165,7 @@ bool StdMeshers_Prism_3D::compute(const Prism_3D::TPrismTopo& thePrism)
 
   // Projections on the top and bottom faces are taken from nodes existing
   // on these faces; find correspondence between bottom and top nodes
-  myUseBlock = false;
+  myUseBlock = false; // is set to true if projection is done using "block approach"
   myBotToColumnMap.clear();
   if ( !assocOrProjBottom2Top( bottomToTopTrsf, thePrism ) ) // it also fills myBotToColumnMap
     return false;
@@ -1181,38 +1173,62 @@ bool StdMeshers_Prism_3D::compute(const Prism_3D::TPrismTopo& thePrism)
 
   // Create nodes inside the block
 
-  // use transformation (issue 0020680, IPAL0052499)
-  StdMeshers_Sweeper sweeper;
-  double tol;
-  bool allowHighBndError;
-
   if ( !myUseBlock )
   {
+    // use transformation (issue 0020680, IPAL0052499) or a "straight line" approach
+    StdMeshers_Sweeper sweeper;
+    sweeper.myHelper  = myHelper;
+    sweeper.myBotFace = thePrism.myBottom;
+    sweeper.myTopFace = thePrism.myTop;
+
     // load boundary nodes into sweeper
     bool dummy;
+    std::set< const SMDS_MeshNode* > usedEndNodes;
     list< TopoDS_Edge >::const_iterator edge = thePrism.myBottomEdges.begin();
     for ( ; edge != thePrism.myBottomEdges.end(); ++edge )
     {
       int edgeID = meshDS->ShapeToIndex( *edge );
       TParam2ColumnMap* u2col = const_cast<TParam2ColumnMap*>
         ( myBlock.GetParam2ColumnMap( edgeID, dummy ));
-      TParam2ColumnMap::iterator u2colIt = u2col->begin();
-      for ( ; u2colIt != u2col->end(); ++u2colIt )
+
+      TParam2ColumnMap::iterator u2colIt = u2col->begin(), u2colEnd = u2col->end();
+      const SMDS_MeshNode* n0 = u2colIt->second[0];
+      const SMDS_MeshNode* n1 = u2col->rbegin()->second[0];
+      if ( !usedEndNodes.insert ( n0 ).second ) ++u2colIt;
+      if ( !usedEndNodes.insert ( n1 ).second ) --u2colEnd;
+
+      for ( ; u2colIt != u2colEnd; ++u2colIt )
         sweeper.myBndColumns.push_back( & u2colIt->second );
     }
-    // load node columns inside the bottom face
+    // load node columns inside the bottom FACE
+    sweeper.myIntColumns.reserve( myBotToColumnMap.size() );
     TNode2ColumnMap::iterator bot_column = myBotToColumnMap.begin();
     for ( ; bot_column != myBotToColumnMap.end(); ++bot_column )
       sweeper.myIntColumns.push_back( & bot_column->second );
 
-    tol = getSweepTolerance( thePrism );
-    allowHighBndError = !isSimpleBottom( thePrism );
-  }
+    myHelper->SetElementsOnShape( true );
 
-  if ( !myUseBlock && sweeper.ComputeNodes( *myHelper, tol, allowHighBndError ))
-  {
+    // If all "vertical" EDGEs are straight, then all nodes of an internal node column
+    // are located on a line connecting the top node and the bottom node.
+    bool isStrightColunm = allVerticalEdgesStraight( thePrism );
+    if ( !isStrightColunm )
+    {
+      double tol = getSweepTolerance( thePrism );
+      bool allowHighBndError = !isSimpleBottom( thePrism );
+      myUseBlock = !sweeper.ComputeNodesByTrsf( tol, allowHighBndError );
+    }
+    else if ( sweeper.CheckSameZ() )
+    {
+      myUseBlock = !sweeper.ComputeNodesOnStraightSameZ();
+    }
+    else
+    {
+      myUseBlock = !sweeper.ComputeNodesOnStraight();
+    }
+    myHelper->SetElementsOnShape( false );
   }
-  else // use block approach
+
+  if ( myUseBlock ) // use block approach
   {
     // loop on nodes inside the bottom face
     Prism_3D::TNode prevBNode;
@@ -1227,6 +1243,14 @@ bool StdMeshers_Prism_3D::compute(const Prism_3D::TPrismTopo& thePrism)
       // column nodes; middle part of the column are zero pointers
       TNodeColumn& column = bot_column->second;
 
+      // check if a column is already computed using non-block approach
+      size_t i;
+      for ( i = 0; i < column.size(); ++i )
+        if ( !column[ i ])
+          break;
+      if ( i == column.size() )
+        continue; // all nodes created
+
       gp_XYZ botParams, topParams;
       if ( !tBotNode.HasParams() )
       {
@@ -1361,6 +1385,75 @@ bool StdMeshers_Prism_3D::compute(const Prism_3D::TPrismTopo& thePrism)
   return true;
 }
 
+//=======================================================================
+//function : computeBase
+//purpose  : Compute the base face of a prism
+//=======================================================================
+
+bool StdMeshers_Prism_3D::computeBase(const Prism_3D::TPrismTopo& thePrism)
+{
+  SMESH_Mesh*     mesh = myHelper->GetMesh();
+  SMESH_subMesh* botSM = mesh->GetSubMesh( thePrism.myBottom );
+  if (( botSM->IsEmpty() ) &&
+      ( ! botSM->GetAlgo() ||
+        ! _gen->Compute( *botSM->GetFather(), botSM->GetSubShape(), /*shapeOnly=*/true )))
+  {
+    // find any applicable algorithm assigned to any FACE of the main shape
+    std::vector< TopoDS_Shape > faces;
+    if ( myPrevBottomSM &&
+         myPrevBottomSM->GetAlgo()->IsApplicableToShape( thePrism.myBottom, /*all=*/false ))
+      faces.push_back( myPrevBottomSM->GetSubShape() );
+
+    TopExp_Explorer faceIt( mesh->GetShapeToMesh(), TopAbs_FACE );
+    for ( ; faceIt.More(); faceIt.Next() )
+      faces.push_back( faceIt.Current() );
+
+    faces.push_back( TopoDS_Shape() ); // to try quadrangle algorithm
+
+    SMESH_Algo* algo = 0;
+    for ( size_t i = 0; i < faces.size() &&  botSM->IsEmpty(); ++i )
+    {
+      if ( faces[i].IsNull() ) algo = TQuadrangleAlgo::instance( this, myHelper );
+      else                     algo = mesh->GetSubMesh( faces[i] )->GetAlgo();
+      if ( algo && algo->IsApplicableToShape( thePrism.myBottom, /*all=*/false ))
+      {
+        // try to compute the bottom FACE
+        if ( algo->NeedDiscreteBoundary() )
+        {
+          // compute sub-shapes
+          SMESH_subMeshIteratorPtr smIt = botSM->getDependsOnIterator(false,false);
+          bool subOK = true;
+          while ( smIt->more() && subOK )
+          {
+            SMESH_subMesh* sub = smIt->next();
+            sub->ComputeStateEngine( SMESH_subMesh::COMPUTE );
+            subOK = sub->IsMeshComputed();
+          }
+          if ( !subOK )
+            continue;
+        }
+        try {
+          OCC_CATCH_SIGNALS;
+          algo->InitComputeError();
+          algo->Compute( *mesh, botSM->GetSubShape() );
+        }
+        catch (...) {
+        }
+      }
+    }
+  }
+
+  if ( botSM->IsEmpty() )
+    return error( COMPERR_BAD_INPUT_MESH,
+                  TCom( "No mesher defined to compute the base face #")
+                  << shapeID( thePrism.myBottom ));
+
+  if ( botSM->GetAlgo() )
+    myPrevBottomSM = botSM;
+
+  return true;
+}
+
 //=======================================================================
 //function : computeWalls
 //purpose  : Compute 2D mesh on walls FACEs of a prism
@@ -1391,6 +1484,7 @@ bool StdMeshers_Prism_3D::computeWalls(const Prism_3D::TPrismTopo& thePrism)
     for ( ; quad != thePrism.myWallQuads[iW].end(); ++quad )
     {
       StdMeshers_FaceSidePtr lftSide = (*quad)->side[ QUAD_LEFT_SIDE ];
+      lftSide->Reverse(); // to go up
       for ( int i = 0; i < lftSide->NbEdges(); ++i )
       {
         ++wgt[ iW ];
@@ -1418,6 +1512,11 @@ bool StdMeshers_Prism_3D::computeWalls(const Prism_3D::TPrismTopo& thePrism)
   for ( size_t iW = 0; iW != nbWalls; ++iW )
     wgt2quad.insert( make_pair( wgt[ iW ], iW ));
 
+  // artificial quads to do outer <-> inner wall projection
+  std::map< int, FaceQuadStruct > iW2oiQuads;
+  std::map< int, FaceQuadStruct >::iterator w2oiq;
+  makeQuadsForOutInProjection( thePrism, wgt2quad, iW2oiQuads );
+
   // Project 'vertical' EDGEs, from left to right
   multimap< int, int >::reverse_iterator w2q = wgt2quad.rbegin();
   for ( ; w2q != wgt2quad.rend(); ++w2q )
@@ -1434,10 +1533,25 @@ bool StdMeshers_Prism_3D::computeWalls(const Prism_3D::TPrismTopo& thePrism)
       if ( swapLeftRight )
         std::swap( lftSide, rgtSide );
 
+      bool isArtificialQuad = (( w2oiq = iW2oiQuads.find( iW )) != iW2oiQuads.end() );
+      if ( isArtificialQuad )
+      {
+        // reset sides to perform the outer <-> inner projection
+        FaceQuadStruct& oiQuad = w2oiq->second;
+        rgtSide = oiQuad.side[ QUAD_RIGHT_SIDE ];
+        lftSide = oiQuad.side[ QUAD_LEFT_SIDE ];
+        iW2oiQuads.erase( w2oiq );
+      }
+
       // assure that all the source (left) EDGEs are meshed
       int nbSrcSegments = 0;
       for ( int i = 0; i < lftSide->NbEdges(); ++i )
       {
+        if ( isArtificialQuad )
+        {
+          nbSrcSegments = lftSide->NbPoints()-1;
+          continue;
+        }
         const TopoDS_Edge& srcE = lftSide->Edge(i);
         SMESH_subMesh*    srcSM = mesh->GetSubMesh( srcE );
         if ( !srcSM->IsMeshComputed() ) {
@@ -1513,7 +1627,7 @@ bool StdMeshers_Prism_3D::computeWalls(const Prism_3D::TPrismTopo& thePrism)
         const UVPtStructVec&  srcNodeStr = lftSide->GetUVPtStruct();
         if ( srcNodeStr.size() == 0 )
           return toSM( error( TCom("Invalid node positions on edge #") <<
-                              shapeID( lftSide->Edge(0) )));
+                              lftSide->EdgeID(0) ));
         vector< SMDS_MeshNode* > newNodes( srcNodeStr.size() );
         for ( int is2ndV = 0; is2ndV < 2; ++is2ndV )
         {
@@ -1521,12 +1635,12 @@ bool StdMeshers_Prism_3D::computeWalls(const Prism_3D::TPrismTopo& thePrism)
           TopoDS_Vertex      v = myHelper->IthVertex( is2ndV, E );
           mesh->GetSubMesh( v )->ComputeStateEngine( SMESH_subMesh::COMPUTE );
           const SMDS_MeshNode* n = SMESH_Algo::VertexNode( v, meshDS );
-          newNodes[ is2ndV ? 0 : newNodes.size()-1 ] = (SMDS_MeshNode*) n;
+          newNodes[ is2ndV ? newNodes.size()-1 : 0 ] = (SMDS_MeshNode*) n;
         }
 
         // compute nodes on target EDGEs
         DBGOUT( "COMPUTE V edge (proj) " << shapeID( lftSide->Edge(0)));
-        rgtSide->Reverse(); // direct it same as the lftSide
+        //rgtSide->Reverse(); // direct it same as the lftSide
         myHelper->SetElementsOnShape( false ); // myHelper holds the prism shape
         TopoDS_Edge tgtEdge;
         for ( size_t iN = 1; iN < srcNodeStr.size()-1; ++iN ) // add nodes
@@ -1695,9 +1809,8 @@ bool StdMeshers_Prism_3D::computeWalls(const Prism_3D::TPrismTopo& thePrism)
 }
 
 //=======================================================================
-/*!
- * \brief Returns a source EDGE of propagation to a given EDGE
- */
+//function : findPropagationSource
+//purpose  : Returns a source EDGE of propagation to a given EDGE
 //=======================================================================
 
 TopoDS_Edge StdMeshers_Prism_3D::findPropagationSource( const TopoDS_Edge& E )
@@ -1710,9 +1823,93 @@ TopoDS_Edge StdMeshers_Prism_3D::findPropagationSource( const TopoDS_Edge& E )
   return TopoDS_Edge();
 }
 
+//=======================================================================
+//function : makeQuadsForOutInProjection
+//purpose  : Create artificial wall quads for vertical projection between
+//           the outer and inner walls
+//=======================================================================
+
+void StdMeshers_Prism_3D::makeQuadsForOutInProjection( const Prism_3D::TPrismTopo& thePrism,
+                                                       multimap< int, int >&       wgt2quad,
+                                                       map< int, FaceQuadStruct >& iQ2oiQuads)
+{
+  if ( thePrism.NbWires() <= 1 )
+    return;
+
+  std::set< int > doneWires; // processed wires
+
+  SMESH_Mesh*      mesh = myHelper->GetMesh();
+  const bool  isForward = true;
+  const bool skipMedium = myHelper->GetIsQuadratic();
+
+  // make a source side for all projections
+
+  multimap< int, int >::reverse_iterator w2q = wgt2quad.rbegin();
+  const int iQuad = w2q->second;
+  const int iWire = getWireIndex( thePrism.myWallQuads[ iQuad ].front() );
+  doneWires.insert( iWire );
+
+  UVPtStructVec srcNodes;
+
+  Prism_3D::TQuadList::const_iterator quad = thePrism.myWallQuads[ iQuad ].begin();
+  for ( ; quad != thePrism.myWallQuads[ iQuad ].end(); ++quad )
+  {
+    StdMeshers_FaceSidePtr lftSide = (*quad)->side[ QUAD_LEFT_SIDE ];
+
+    // assure that all the source (left) EDGEs are meshed
+    for ( int i = 0; i < lftSide->NbEdges(); ++i )
+    {
+      const TopoDS_Edge& srcE = lftSide->Edge(i);
+      SMESH_subMesh*    srcSM = mesh->GetSubMesh( srcE );
+      if ( !srcSM->IsMeshComputed() ) {
+        srcSM->ComputeSubMeshStateEngine( SMESH_subMesh::COMPUTE );
+        srcSM->ComputeStateEngine       ( SMESH_subMesh::COMPUTE );
+      }
+      if ( !srcSM->IsMeshComputed() )
+        return;
+    }
+    const UVPtStructVec& subNodes = lftSide->GetUVPtStruct();
+    UVPtStructVec::const_iterator subBeg = subNodes.begin(), subEnd = subNodes.end();
+    if ( !srcNodes.empty() ) ++subBeg;
+    srcNodes.insert( srcNodes.end(), subBeg, subEnd );
+  }
+  StdMeshers_FaceSidePtr srcSide = StdMeshers_FaceSide::New( srcNodes );
+
+  // make the quads
+
+  list< TopoDS_Edge > sideEdges;
+  TopoDS_Face face;
+  for ( ++w2q; w2q != wgt2quad.rend(); ++w2q )
+  {
+    const int                  iQuad = w2q->second;
+    const Prism_3D::TQuadList& quads = thePrism.myWallQuads[ iQuad ];
+    const int                  iWire = getWireIndex( quads.front() );
+    if ( !doneWires.insert( iWire ).second )
+      continue;
+
+    sideEdges.clear();
+    for ( quad = quads.begin(); quad != quads.end(); ++quad )
+    {
+      StdMeshers_FaceSidePtr lftSide = (*quad)->side[ QUAD_LEFT_SIDE ];
+      for ( int i = 0; i < lftSide->NbEdges(); ++i )
+        sideEdges.push_back( lftSide->Edge( i ));
+      face = lftSide->Face();
+    }
+    StdMeshers_FaceSidePtr tgtSide =
+      StdMeshers_FaceSide::New( face, sideEdges, mesh, isForward, skipMedium, myHelper );
+
+    FaceQuadStruct& newQuad = iQ2oiQuads[ iQuad ];
+    newQuad.side.resize( 4 );
+    newQuad.side[ QUAD_LEFT_SIDE  ] = srcSide;
+    newQuad.side[ QUAD_RIGHT_SIDE ] = tgtSide;
+
+    wgt2quad.insert( *w2q ); // to process this quad after processing the newQuad
+  }
+}
+
 //=======================================================================
 //function : Evaluate
-//purpose  : 
+//purpose  :
 //=======================================================================
 
 bool StdMeshers_Prism_3D::Evaluate(SMESH_Mesh&         theMesh,
@@ -2094,7 +2291,7 @@ bool StdMeshers_Prism_3D::assocOrProjBottom2Top( const gp_Trsf & bottomToTopTrsf
     TNode2ColumnMap::iterator bN_col =
       myBotToColumnMap.insert( make_pair ( bN, TNodeColumn() )).first;
     TNodeColumn & column = bN_col->second;
-    column.resize( zSize );
+    column.resize( zSize, 0 );
     column.front() = botNode;
     column.back()  = topNode;
   }
@@ -2274,7 +2471,7 @@ bool StdMeshers_Prism_3D::projectBottomToTop( const gp_Trsf &             bottom
 
   // Check the projected mesh
 
-  if ( thePrism.myNbEdgesInWires.size() > 1 && // there are holes
+  if ( thePrism.NbWires() > 1 && // there are holes
        topHelper.IsDistorted2D( topSM, /*checkUV=*/false ))
   {
     SMESH_MeshEditor editor( topHelper.GetMesh() );
@@ -2393,14 +2590,14 @@ double StdMeshers_Prism_3D::getSweepTolerance( const Prism_3D::TPrismTopo& thePr
 
 //=======================================================================
 //function : isSimpleQuad
-//purpose  : check if the bottom FACE is meshable with nice qudrangles,
+//purpose  : check if the bottom FACE is meshable with nice quadrangles,
 //           if so the block aproach can work rather fast.
 //           This is a temporary mean caused by problems in StdMeshers_Sweeper
 //=======================================================================
 
 bool StdMeshers_Prism_3D::isSimpleBottom( const Prism_3D::TPrismTopo& thePrism )
 {
-  if ( thePrism.myBottomEdges.size() != 4 )
+  if ( thePrism.myNbEdgesInWires.front() != 4 )
     return false;
 
   // analyse angles between edges
@@ -2432,6 +2629,43 @@ bool StdMeshers_Prism_3D::isSimpleBottom( const Prism_3D::TPrismTopo& thePrism )
   return true;
 }
 
+//=======================================================================
+//function : allVerticalEdgesStraight
+//purpose  : Defines if all "vertical" EDGEs are straight
+//=======================================================================
+
+bool StdMeshers_Prism_3D::allVerticalEdgesStraight( const Prism_3D::TPrismTopo& thePrism )
+{
+  for ( size_t i = 0; i < thePrism.myWallQuads.size(); ++i )
+  {
+    const Prism_3D::TQuadList& quads = thePrism.myWallQuads[i];
+    Prism_3D::TQuadList::const_iterator quadIt = quads.begin();
+    TopoDS_Edge prevQuadEdge;
+    for ( ; quadIt != quads.end(); ++quadIt )
+    {
+      StdMeshers_FaceSidePtr rightSide = (*quadIt)->side[ QUAD_RIGHT_SIDE ];
+
+      if ( !prevQuadEdge.IsNull() &&
+           !SMESH_Algo::IsContinuous( rightSide->Edge( 0 ), prevQuadEdge ))
+        return false;
+
+      for ( int iE = 0; iE < rightSide->NbEdges(); ++iE )
+      {
+        const TopoDS_Edge & rightE = rightSide->Edge( iE );
+        if ( !SMESH_Algo::IsStraight( rightE, /*degenResult=*/true ))
+          return false;
+
+        if ( iE > 0 &&
+             !SMESH_Algo::IsContinuous( rightSide->Edge( iE-1 ), rightE ))
+          return false;
+
+        prevQuadEdge = rightE;
+      }
+    }
+  }
+  return true;
+}
+
 //=======================================================================
 //function : project2dMesh
 //purpose  : Project mesh faces from a source FACE of one prism (theSrcFace)
@@ -3364,10 +3598,10 @@ bool StdMeshers_PrismAsBlock::Init(SMESH_MesherHelper*         helper,
       if ( !myHelper->LoadNodeColumns( faceColumns, (*quad)->face, quadBot, meshDS ))
         return error(COMPERR_BAD_INPUT_MESH, TCom("Can't find regular quadrangle mesh ")
                      << "on a side face #" << MeshDS()->ShapeToIndex( (*quad)->face ));
-
-      if ( !faceColumns.empty() && (int)faceColumns.begin()->second.size() != VerticalSize() )
-        return error(COMPERR_BAD_INPUT_MESH, "Different 'vertical' discretization");
     }
+    if ( !faceColumns.empty() && (int)faceColumns.begin()->second.size() != VerticalSize() )
+      return error(COMPERR_BAD_INPUT_MESH, "Different 'vertical' discretization");
+
     // edge columns
     int id = MeshDS()->ShapeToIndex( *edgeIt );
     bool isForward = true; // meaningless for intenal wires
@@ -4667,6 +4901,7 @@ bool StdMeshers_Sweeper::projectIntPoints(const vector< gp_XYZ >&    fromBndPoin
                                           const vector< gp_XYZ >&    toBndPoints,
                                           const vector< gp_XYZ >&    fromIntPoints,
                                           vector< gp_XYZ >&          toIntPoints,
+                                          const double               r,
                                           NSProjUtils::TrsfFinder3D& trsf,
                                           vector< gp_XYZ > *         bndError)
 {
@@ -4691,54 +4926,34 @@ bool StdMeshers_Sweeper::projectIntPoints(const vector< gp_XYZ >&    fromBndPoin
       (*bndError)[ iP ]  = toBndPoints[ iP ] - fromTrsf;
     }
   }
-  return true;
-}
-
-//================================================================================
-/*!
- * \brief Add boundary error to ineternal points
- */
-//================================================================================
 
-void StdMeshers_Sweeper::applyBoundaryError(const vector< gp_XYZ >& bndPoints,
-                                            const vector< gp_XYZ >& bndError1,
-                                            const vector< gp_XYZ >& bndError2,
-                                            const double            r,
-                                            vector< gp_XYZ >&       intPoints,
-                                            vector< double >&       int2BndDist)
-{
-  // fix each internal point
-  const double eps = 1e-100;
-  for ( size_t iP = 0; iP < intPoints.size(); ++iP )
+  // apply boundary error
+  if ( bndError && toIntPoints.size() == myTopBotTriangles.size() )
   {
-    gp_XYZ & intPnt = intPoints[ iP ];
-
-    // compute distance from intPnt to each boundary node
-    double int2BndDistSum = 0;
-    for ( size_t iBnd = 0; iBnd < bndPoints.size(); ++iBnd )
-    {
-      int2BndDist[ iBnd ] = 1 / (( intPnt - bndPoints[ iBnd ]).SquareModulus() + eps );
-      int2BndDistSum += int2BndDist[ iBnd ];
-    }
-
-    // apply bndError
-    for ( size_t iBnd = 0; iBnd < bndPoints.size(); ++iBnd )
+    for ( size_t iP = 0; iP < toIntPoints.size(); ++iP )
     {
-      intPnt += bndError1[ iBnd ] * ( 1 - r ) * int2BndDist[ iBnd ] / int2BndDistSum;
-      intPnt += bndError2[ iBnd ] * r         * int2BndDist[ iBnd ] / int2BndDistSum;
+      const TopBotTriangles& tbTrias = myTopBotTriangles[ iP ];
+      for ( int i = 0; i < 3; ++i ) // boundary errors at 3 triangle nodes
+      {
+        toIntPoints[ iP ] +=
+          ( (*bndError)[ tbTrias.myBotTriaNodes[i] ] * tbTrias.myBotBC[i] * ( 1 - r ) +
+            (*bndError)[ tbTrias.myTopTriaNodes[i] ] * tbTrias.myTopBC[i] * ( r     ));
+      }
     }
   }
+
+  return true;
 }
 
 //================================================================================
 /*!
- * \brief Creates internal nodes of the prism
+ * \brief Create internal nodes of the prism by computing an affine transformation
+ *        from layer to layer
  */
 //================================================================================
 
-bool StdMeshers_Sweeper::ComputeNodes( SMESH_MesherHelper& helper,
-                                       const double        tol,
-                                       const bool          allowHighBndError)
+bool StdMeshers_Sweeper::ComputeNodesByTrsf( const double tol,
+                                             const bool   allowHighBndError)
 {
   const size_t zSize = myBndColumns[0]->size();
   const size_t zSrc = 0, zTgt = zSize-1;
@@ -4754,6 +4969,10 @@ bool StdMeshers_Sweeper::ComputeNodes( SMESH_MesherHelper& helper,
     intPntsOfLayer[ zTgt ][ iP ] = intPoint( iP, zTgt );
   }
 
+  // for each internal column find boundary nodes whose error to use for correction
+  prepareTopBotDelaunay();
+  bool isErrorCorrectable = findDelaunayTriangles();
+
   // compute coordinates of internal nodes by projecting (transfroming) src and tgt
   // nodes towards the central layer
 
@@ -4780,10 +4999,12 @@ bool StdMeshers_Sweeper::ComputeNodes( SMESH_MesherHelper& helper,
     }
     if (! projectIntPoints( fromSrcBndPnts, toSrcBndPnts,
                             intPntsOfLayer[ zS-1 ], intPntsOfLayer[ zS ],
+                            zS / ( zSize - 1.),
                             trsfOfLayer   [ zS-1 ], & bndError[ zS-1 ]))
       return false;
     if (! projectIntPoints( fromTgtBndPnts, toTgtBndPnts,
                             intPntsOfLayer[ zT+1 ], intPntsOfLayer[ zT ],
+                            zT / ( zSize - 1.),
                             trsfOfLayer   [ zT+1 ], & bndError[ zT+1 ]))
       return false;
 
@@ -4808,6 +5029,22 @@ bool StdMeshers_Sweeper::ComputeNodes( SMESH_MesherHelper& helper,
     fromSrcBndPnts.swap( toSrcBndPnts );
   }
 
+  // Evaluate an error of boundary points
+
+  if ( !isErrorCorrectable && !allowHighBndError )
+  {
+    for ( size_t iP = 0; iP < myBndColumns.size(); ++iP )
+    {
+      double sumError = 0;
+      for ( size_t z = 1; z < zS; ++z ) // loop on layers
+        sumError += ( bndError[ z-1     ][ iP ].Modulus() +
+                      bndError[ zSize-z ][ iP ].Modulus() );
+
+      if ( sumError > tol )
+        return false;
+    }
+  }
+
   // Compute two projections of internal points to the central layer
   // in order to evaluate an error of internal points
 
@@ -4822,10 +5059,12 @@ bool StdMeshers_Sweeper::ComputeNodes( SMESH_MesherHelper& helper,
   }
   if (! projectIntPoints( fromSrcBndPnts, toSrcBndPnts,
                           intPntsOfLayer[ zS-1 ], centerSrcIntPnts,
+                          zS / ( zSize - 1.),
                           trsfOfLayer   [ zS-1 ], & bndError[ zS-1 ]))
     return false;
   if (! projectIntPoints( fromTgtBndPnts, toTgtBndPnts,
                           intPntsOfLayer[ zT+1 ], centerTgtIntPnts,
+                          zT / ( zSize - 1.),
                           trsfOfLayer   [ zT+1 ], & bndError[ zT+1 ]))
     return false;
 
@@ -4844,24 +5083,7 @@ bool StdMeshers_Sweeper::ComputeNodes( SMESH_MesherHelper& helper,
         (intPntsOfLayer[ zS-1 ][ iP ] - centerTgtIntPnts[ iP ]).SquareModulus() < tol*tol;
   }
 
-  // Evaluate an error of boundary points
-
-  bool bndErrorIsSmall = true;
-  for ( size_t iP = 0; ( iP < myBndColumns.size() && bndErrorIsSmall ); ++iP )
-  {
-    double sumError = 0;
-    for ( size_t z = 1; z < zS; ++z ) // loop on layers
-      sumError += ( bndError[ z-1     ][ iP ].Modulus() +
-                    bndError[ zSize-z ][ iP ].Modulus() );
-
-    bndErrorIsSmall = ( sumError < tol );
-  }
-
-  if ( !bndErrorIsSmall && !allowHighBndError )
-    return false;
-
   // compute final points on the central layer
-  std::vector< double > int2BndDist( myBndColumns.size() ); // work array of applyBoundaryError()
   double r = zS / ( zSize - 1.);
   if ( zS == zT )
   {
@@ -4870,11 +5092,6 @@ bool StdMeshers_Sweeper::ComputeNodes( SMESH_MesherHelper& helper,
       intPntsOfLayer[ zS ][ iP ] =
         ( 1 - r ) * centerSrcIntPnts[ iP ] + r * centerTgtIntPnts[ iP ];
     }
-    if ( !bndErrorIsSmall )
-    {
-      applyBoundaryError( toSrcBndPnts, bndError[ zS-1 ], bndError[ zS+1 ], r,
-                          intPntsOfLayer[ zS ], int2BndDist );
-    }
   }
   else
   {
@@ -4885,17 +5102,8 @@ bool StdMeshers_Sweeper::ComputeNodes( SMESH_MesherHelper& helper,
       intPntsOfLayer[ zT ][ iP ] =
         r * intPntsOfLayer[ zT ][ iP ] + ( 1 - r ) * centerTgtIntPnts[ iP ];
     }
-    if ( !bndErrorIsSmall )
-    {
-      applyBoundaryError( toSrcBndPnts, bndError[ zS-1 ], bndError[ zS+1 ], r,
-                          intPntsOfLayer[ zS ], int2BndDist );
-      applyBoundaryError( toTgtBndPnts, bndError[ zT+1 ], bndError[ zT-1 ], r,
-                          intPntsOfLayer[ zT ], int2BndDist );
-    }
   }
 
-  centerIntErrorIsSmall = true; // 3D_mesh_Extrusion_00/A3
-  bndErrorIsSmall = true;
   if ( !centerIntErrorIsSmall )
   {
     // Compensate the central error; continue adding projection
@@ -4927,9 +5135,11 @@ bool StdMeshers_Sweeper::ComputeNodes( SMESH_MesherHelper& helper,
       }
       projectIntPoints( fromSrcBndPnts, toSrcBndPnts,
                         fromSrcIntPnts, toSrcIntPnts,
+                        zS / ( zSize - 1.),
                         trsfOfLayer[ zS+1 ], & srcBndError );
       projectIntPoints( fromTgtBndPnts, toTgtBndPnts,
                         fromTgtIntPnts, toTgtIntPnts,
+                        zT / ( zSize - 1.),
                         trsfOfLayer[ zT-1 ], & tgtBndError );
 
       // if ( zS == zTgt - 1 )
@@ -4960,15 +5170,6 @@ bool StdMeshers_Sweeper::ComputeNodes( SMESH_MesherHelper& helper,
         zTIntPnts[ iP ] = r * zTIntPnts[ iP ]  +  ( 1 - r ) * toTgtIntPnts[ iP ];
       }
 
-      // compensate bnd error
-      if ( !bndErrorIsSmall )
-      {
-        applyBoundaryError( toSrcBndPnts, srcBndError, bndError[ zS+1 ], r,
-                            intPntsOfLayer[ zS ], int2BndDist );
-        applyBoundaryError( toTgtBndPnts, tgtBndError, bndError[ zT-1 ], r,
-                            intPntsOfLayer[ zT ], int2BndDist );
-      }
-
       fromSrcBndPnts.swap( toSrcBndPnts );
       fromSrcIntPnts.swap( toSrcIntPnts );
       fromTgtBndPnts.swap( toTgtBndPnts );
@@ -4976,27 +5177,8 @@ bool StdMeshers_Sweeper::ComputeNodes( SMESH_MesherHelper& helper,
     }
   }  // if ( !centerIntErrorIsSmall )
 
-  else if ( !bndErrorIsSmall )
-  {
-    zS = zSrc + 1;
-    zT = zTgt - 1;
-    for ( ; zS < zT; ++zS, --zT ) // vertical loop on layers
-    {
-      for ( size_t iP = 0; iP < myBndColumns.size(); ++iP )
-      {
-        toSrcBndPnts[ iP ] = bndPoint( iP, zS );
-        toTgtBndPnts[ iP ] = bndPoint( iP, zT );
-      }
-      // compensate bnd error
-      applyBoundaryError( toSrcBndPnts, bndError[ zS-1 ], bndError[ zS-1 ], 0.5,
-                          intPntsOfLayer[ zS ], int2BndDist );
-      applyBoundaryError( toTgtBndPnts, bndError[ zT+1 ], bndError[ zT+1 ], 0.5,
-                          intPntsOfLayer[ zT ], int2BndDist );
-    }
-  }
 
-  // cout << "centerIntErrorIsSmall = " << centerIntErrorIsSmall<< endl;
-  // cout << "bndErrorIsSmall = " << bndErrorIsSmall<< endl;
+  //cout << "centerIntErrorIsSmall = " << centerIntErrorIsSmall<< endl;
 
   // Create nodes
   for ( size_t iP = 0; iP < myIntColumns.size(); ++iP )
@@ -5005,10 +5187,304 @@ bool StdMeshers_Sweeper::ComputeNodes( SMESH_MesherHelper& helper,
     for ( size_t z = zSrc + 1; z < zTgt; ++z ) // vertical loop on layers
     {
       const gp_XYZ & xyz = intPntsOfLayer[ z ][ iP ];
-      if ( !( nodeCol[ z ] = helper.AddNode( xyz.X(), xyz.Y(), xyz.Z() )))
+      if ( !( nodeCol[ z ] = myHelper->AddNode( xyz.X(), xyz.Y(), xyz.Z() )))
         return false;
     }
   }
 
   return true;
 }
+
+//================================================================================
+/*!
+ * \brief Check if all nodes of each layers have same logical Z
+ */
+//================================================================================
+
+bool StdMeshers_Sweeper::CheckSameZ()
+{
+  myZColumns.resize( myBndColumns.size() );
+  fillZColumn( myZColumns[0], *myBndColumns[0] );
+
+  bool sameZ = true;
+  const double tol = 0.1 * 1./ myBndColumns[0]->size();
+
+  // check columns based on VERTEXes
+
+  vector< int > vertexIndex;
+  vertexIndex.push_back( 0 );
+  for ( size_t iC = 1; iC < myBndColumns.size() &&  sameZ; ++iC )
+  {
+    if ( myBndColumns[iC]->front()->GetPosition()->GetDim() > 0 )
+      continue; // not on VERTEX
+
+    vertexIndex.push_back( iC );
+    fillZColumn( myZColumns[iC], *myBndColumns[iC] );
+
+    for ( size_t iZ = 0; iZ < myZColumns[0].size() &&  sameZ; ++iZ )
+      sameZ = ( Abs( myZColumns[0][iZ] - myZColumns[iC][iZ]) < tol );
+  }
+
+  // check columns based on EDGEs, one per EDGE
+
+  for ( size_t i = 1; i < vertexIndex.size() &&  sameZ; ++i )
+  {
+    if ( vertexIndex[i] - vertexIndex[i-1] < 2 )
+      continue;
+
+    int iC = ( vertexIndex[i] + vertexIndex[i-1] ) / 2;
+    fillZColumn( myZColumns[iC], *myBndColumns[iC] );
+
+    for ( size_t iZ = 0; iZ < myZColumns[0].size() &&  sameZ; ++iZ )
+      sameZ = ( Abs( myZColumns[0][iZ] - myZColumns[iC][iZ]) < tol );
+  }
+
+  if ( sameZ )
+  {
+    myZColumns.resize(1);
+  }
+  else
+  {
+    for ( size_t iC = 1; iC < myBndColumns.size(); ++iC )
+      fillZColumn( myZColumns[iC], *myBndColumns[iC] );
+  }
+
+  return sameZ;
+}
+
+//================================================================================
+/*!
+ * \brief Create internal nodes of the prism all located on straight lines with
+ *        the same distribution along the lines.
+ */
+//================================================================================
+
+bool StdMeshers_Sweeper::ComputeNodesOnStraightSameZ()
+{
+  TZColumn& z = myZColumns[0];
+
+  for ( size_t i = 0; i < myIntColumns.size(); ++i )
+  {
+    TNodeColumn& nodes = *myIntColumns[i];
+    SMESH_NodeXYZ n0( nodes[0] ), n1( nodes.back() );
+
+    for ( size_t iZ = 0; iZ < z.size(); ++iZ )
+    {
+      gp_XYZ p = n0 * ( 1 - z[iZ] ) + n1 * z[iZ];
+      nodes[ iZ+1 ] = myHelper->AddNode( p.X(), p.Y(), p.Z() );
+    }
+  }
+
+  return true;
+}
+
+//================================================================================
+/*!
+ * \brief Create internal nodes of the prism all located on straight lines with
+ *        different distributions along the lines.
+ */
+//================================================================================
+
+bool StdMeshers_Sweeper::ComputeNodesOnStraight()
+{
+  prepareTopBotDelaunay();
+
+  const SMDS_MeshNode     *botNode, *topNode;
+  const BRepMesh_Triangle *topTria;
+  double botBC[3], topBC[3]; // barycentric coordinates
+  int    botTriaNodes[3], topTriaNodes[3];
+  bool   checkUV = true;
+
+  int nbInternalNodes = myIntColumns.size();
+  myBotDelaunay->InitTraversal( nbInternalNodes );
+
+  while (( botNode = myBotDelaunay->NextNode( botBC, botTriaNodes )))
+  {
+    TNodeColumn* column = myIntColumns[ myNodeID2ColID( botNode->GetID() )];
+
+    // find a Delaunay triangle containing the topNode
+    topNode = column->back();
+    gp_XY topUV = myHelper->GetNodeUV( myTopFace, topNode, NULL, &checkUV );
+    // get a starting triangle basing on that top and bot boundary nodes have same index
+    topTria = myTopDelaunay->GetTriangleNear( botTriaNodes[0] );
+    topTria = myTopDelaunay->FindTriangle( topUV, topTria, topBC, topTriaNodes );
+    if ( !topTria )
+      return false;
+
+    // create nodes along a line
+    SMESH_NodeXYZ botP( botNode ), topP( topNode );
+    for ( size_t iZ = 0; iZ < myZColumns[0].size(); ++iZ )
+    {
+      // use barycentric coordinates as weight of Z of boundary columns
+      double botZ = 0, topZ = 0;
+      for ( int i = 0; i < 3; ++i )
+      {
+        botZ += botBC[i] * myZColumns[ botTriaNodes[i] ][ iZ ];
+        topZ += topBC[i] * myZColumns[ topTriaNodes[i] ][ iZ ];
+      }
+      double rZ = double( iZ + 1 ) / ( myZColumns[0].size() + 1 );
+      double z = botZ * ( 1 - rZ ) + topZ * rZ;
+      gp_XYZ p = botP * ( 1 - z  ) + topP * z;
+      (*column)[ iZ+1 ] = myHelper->AddNode( p.X(), p.Y(), p.Z() );
+    }
+  }
+
+  return myBotDelaunay->NbVisitedNodes() == nbInternalNodes;
+}
+
+//================================================================================
+/*!
+ * \brief Compute Z of nodes of a straight column
+ */
+//================================================================================
+
+void StdMeshers_Sweeper::fillZColumn( TZColumn&    zColumn,
+                                      TNodeColumn& nodes )
+{
+  if ( zColumn.size() == nodes.size() - 2 )
+    return;
+
+  gp_Pnt p0 = SMESH_NodeXYZ( nodes[0] );
+  gp_Vec line( p0, SMESH_NodeXYZ( nodes.back() ));
+  double len2 = line.SquareMagnitude();
+
+  zColumn.resize( nodes.size() - 2 );
+  for ( size_t i = 0; i < zColumn.size(); ++i )
+  {
+    gp_Vec vec( p0, SMESH_NodeXYZ( nodes[ i+1] ));
+    zColumn[i] = ( line * vec ) / len2; // param [0,1] on the line
+  }
+}
+
+//================================================================================
+/*!
+ * \brief Initialize *Delaunay members
+ */
+//================================================================================
+
+void StdMeshers_Sweeper::prepareTopBotDelaunay()
+{
+  UVPtStructVec botUV( myBndColumns.size() );
+  UVPtStructVec topUV( myBndColumns.size() );
+  for ( size_t i = 0; i < myBndColumns.size(); ++i )
+  {
+    TNodeColumn& nodes = *myBndColumns[i];
+    botUV[i].node = nodes[0];
+    botUV[i].SetUV( myHelper->GetNodeUV( myBotFace, nodes[0] ));
+    topUV[i].node = nodes.back();
+    topUV[i].SetUV( myHelper->GetNodeUV( myTopFace, nodes.back() ));
+    botUV[i].node->setIsMarked( true );
+  }
+  TopoDS_Edge dummyE;
+  SMESH_Mesh* mesh = myHelper->GetMesh();
+  TSideVector botWires( 1, StdMeshers_FaceSide::New( botUV, myBotFace, dummyE, mesh ));
+  TSideVector topWires( 1, StdMeshers_FaceSide::New( topUV, myTopFace, dummyE, mesh ));
+
+  // Delaunay mesh on the FACEs.
+  bool checkUV = false;
+  myBotDelaunay.reset( new NSProjUtils::Delaunay( botWires, checkUV ));
+  myTopDelaunay.reset( new NSProjUtils::Delaunay( topWires, checkUV ));
+
+  if ( myHelper->GetIsQuadratic() )
+  {
+    // mark all medium nodes of faces on botFace to avoid their treating
+    SMESHDS_SubMesh* smDS = myHelper->GetMeshDS()->MeshElements( myBotFace );
+    SMDS_ElemIteratorPtr eIt = smDS->GetElements();
+    while ( eIt->more() )
+    {
+      const SMDS_MeshElement* e = eIt->next();
+      for ( int i = e->NbCornerNodes(), nb = e->NbNodes(); i < nb; ++i )
+        e->GetNode( i )->setIsMarked( true );
+    }
+  }
+
+  // map to get a node column by a bottom node
+  myNodeID2ColID.Clear(/*doReleaseMemory=*/false);
+  myNodeID2ColID.ReSize( myIntColumns.size() );
+
+  // un-mark nodes to treat (internal bottom nodes) to be returned by myBotDelaunay
+  for ( size_t i = 0; i < myIntColumns.size(); ++i )
+  {
+    const SMDS_MeshNode* botNode = myIntColumns[i]->front();
+    botNode->setIsMarked( false );
+    myNodeID2ColID.Bind( botNode->GetID(), i );
+  }
+}
+
+//================================================================================
+/*!
+ * \brief For each internal node column, find Delaunay triangles including it
+ *        and Barycentric Coordinates within the triangles. Fill in myTopBotTriangles
+ */
+//================================================================================
+
+bool StdMeshers_Sweeper::findDelaunayTriangles()
+{
+  const SMDS_MeshNode     *botNode, *topNode;
+  const BRepMesh_Triangle *topTria;
+  TopBotTriangles          tbTrias;
+  bool  checkUV = true;
+
+  int nbInternalNodes = myIntColumns.size();
+  myTopBotTriangles.resize( nbInternalNodes );
+
+  myBotDelaunay->InitTraversal( nbInternalNodes );
+
+  while (( botNode = myBotDelaunay->NextNode( tbTrias.myBotBC, tbTrias.myBotTriaNodes )))
+  {
+    int colID = myNodeID2ColID( botNode->GetID() );
+    TNodeColumn* column = myIntColumns[ colID ];
+
+    // find a Delaunay triangle containing the topNode
+    topNode = column->back();
+    gp_XY topUV = myHelper->GetNodeUV( myTopFace, topNode, NULL, &checkUV );
+    // get a starting triangle basing on that top and bot boundary nodes have same index
+    topTria = myTopDelaunay->GetTriangleNear( tbTrias.myBotTriaNodes[0] );
+    topTria = myTopDelaunay->FindTriangle( topUV, topTria,
+                                           tbTrias.myTopBC, tbTrias.myTopTriaNodes );
+    if ( !topTria )
+      tbTrias.SetTopByBottom();
+
+    myTopBotTriangles[ colID ] = tbTrias;
+  }
+
+  if ( myBotDelaunay->NbVisitedNodes() < nbInternalNodes )
+  {
+    myTopBotTriangles.clear();
+    return false;
+  }
+
+  myBotDelaunay.reset();
+  myTopDelaunay.reset();
+  myNodeID2ColID.Clear();
+
+  return true;
+}
+
+//================================================================================
+/*!
+ * \brief Initialize fields
+ */
+//================================================================================
+
+StdMeshers_Sweeper::TopBotTriangles::TopBotTriangles()
+{
+  myBotBC[0] = myBotBC[1] = myBotBC[2] = myTopBC[0] = myTopBC[1] = myTopBC[2] = 0.;
+  myBotTriaNodes[0] = myBotTriaNodes[1] = myBotTriaNodes[2] = 0;
+  myTopTriaNodes[0] = myTopTriaNodes[1] = myTopTriaNodes[2] = 0;
+}
+
+//================================================================================
+/*!
+ * \brief Set top data equal to bottom data
+ */
+//================================================================================
+
+void StdMeshers_Sweeper::TopBotTriangles::SetTopByBottom()
+{
+  for ( int i = 0; i < 3; ++i )
+  {
+    myTopBC[i]        = myBotBC[i];
+    myTopTriaNodes[i] = myBotTriaNodes[0];
+  }
+}
index ddfbff96a13a5c917b54248cfedad4d506334b9b..62f0b9a14e83de74ec678e8d7f6e6ea08dcbb159 100644 (file)
 
 #include "SMESH_StdMeshers.hxx"
 
-#include "SMDS_MeshNode.hxx"
-#include "SMDS_TypeOfPosition.hxx"
 #include "SMESHDS_Mesh.hxx"
-#include "SMESH_Algo.hxx"
 #include "SMESH_Block.hxx"
 #include "SMESH_Comment.hxx"
 #include "SMESH_Mesh.hxx"
 #include "SMESH_MesherHelper.hxx"
 #include "SMESH_TypeDefs.hxx"
 #include "SMESH_subMesh.hxx"
+#include "StdMeshers_ProjectionUtils.hxx"
 
 #include <Adaptor2d_Curve2d.hxx>
 #include <Adaptor3d_Curve.hxx>
 #include <Adaptor3d_Surface.hxx>
 #include <BRepAdaptor_Surface.hxx>
+#include <TColStd_DataMapOfIntegerInteger.hxx>
 #include <TopTools_IndexedMapOfOrientedShape.hxx>
 #include <TopoDS_Face.hxx>
 #include <gp_Trsf.hxx>
@@ -56,10 +55,6 @@ namespace Prism_3D
   struct TNode;
   struct TPrismTopo;
 }
-namespace StdMeshers_ProjectionUtils
-{
-  class TrsfFinder3D;
-}
 class SMESHDS_SubMesh;
 class TopoDS_Edge;
 
@@ -106,12 +101,14 @@ namespace Prism_3D
     TopoDS_Face              myBottom;
     TopoDS_Face              myTop;
     std::list< TopoDS_Edge > myBottomEdges;
-    std::vector< TQuadList>  myWallQuads; // wall sides can be vertically composite
+    std::vector< TQuadList>  myWallQuads;      // wall sides can be vertically composite
     std::vector< int >       myRightQuadIndex; // index of right neighbour wall quad
     std::list< int >         myNbEdgesInWires;
 
     bool                     myNotQuadOnTop;
 
+    size_t NbWires() const { return myNbEdgesInWires.size(); }
+
     void Clear();
     void SetUpsideDown();
   };
@@ -418,12 +415,22 @@ private:
  */
 struct StdMeshers_Sweeper
 {
+  // input data
+  SMESH_MesherHelper*         myHelper;
+  TopoDS_Face                 myBotFace;
+  TopoDS_Face                 myTopFace;
   std::vector< TNodeColumn* > myBndColumns; // boundary nodes
+  // output data
   std::vector< TNodeColumn* > myIntColumns; // internal nodes
 
-  bool ComputeNodes( SMESH_MesherHelper& helper,
-                     const double        tol,
-                     const bool          allowHighBndError );
+  bool ComputeNodesByTrsf( const double tol,
+                           const bool   allowHighBndError );
+
+  bool CheckSameZ();
+
+  bool ComputeNodesOnStraightSameZ();
+
+  bool ComputeNodesOnStraight();
 
 private:
 
@@ -433,19 +440,36 @@ private:
   gp_XYZ intPoint( int iP, int z ) const
   { return SMESH_TNodeXYZ( (*myIntColumns[ iP ])[ z ]); }
 
-  static bool projectIntPoints(const std::vector< gp_XYZ >& fromBndPoints,
-                               const std::vector< gp_XYZ >& toBndPoints,
-                               const std::vector< gp_XYZ >& fromIntPoints,
-                               std::vector< gp_XYZ >&       toIntPoints,
-                               StdMeshers_ProjectionUtils::TrsfFinder3D& trsf,
-                               std::vector< gp_XYZ > *      bndError);
-
-  static void applyBoundaryError(const std::vector< gp_XYZ >& bndPoints,
-                                 const std::vector< gp_XYZ >& bndError1,
-                                 const std::vector< gp_XYZ >& bndError2,
-                                 const double                 r,
-                                 std::vector< gp_XYZ >&       toIntPoints,
-                                 std::vector< double >&       int2BndDist);
+  bool projectIntPoints(const std::vector< gp_XYZ >& fromBndPoints,
+                        const std::vector< gp_XYZ >& toBndPoints,
+                        const std::vector< gp_XYZ >& fromIntPoints,
+                        std::vector< gp_XYZ >&       toIntPoints,
+                        const double                 r,
+                        StdMeshers_ProjectionUtils::TrsfFinder3D& trsf,
+                        std::vector< gp_XYZ > *      bndError);
+
+  typedef std::vector< double > TZColumn;
+  static void fillZColumn( TZColumn&    zColumn,
+                           TNodeColumn& nodes );
+
+  void prepareTopBotDelaunay();
+  bool findDelaunayTriangles();
+
+  std::vector< TZColumn >                 myZColumns; // Z distribution of boundary nodes
+
+  StdMeshers_ProjectionUtils::DelaunayPtr myTopDelaunay;
+  StdMeshers_ProjectionUtils::DelaunayPtr myBotDelaunay;
+  TColStd_DataMapOfIntegerInteger         myNodeID2ColID;
+
+  // top and bottom Delaulay triangles including an internal column
+  struct TopBotTriangles
+  {
+    double myBotBC[3], myTopBC[3]; // barycentric coordinates of a node within a triangle
+    int    myBotTriaNodes[3], myTopTriaNodes[3]; // indices of boundary columns
+    TopBotTriangles();
+    void SetTopByBottom();
+  };
+  std::vector< TopBotTriangles> myTopBotTriangles;
 };
 
 // ===============================================
@@ -486,6 +510,10 @@ public:
                          SMESH_MesherHelper*               helper);
 
   static bool IsApplicable(const TopoDS_Shape & aShape, bool toCheckAll);
+  virtual bool IsApplicableToShape(const TopoDS_Shape & shape, bool toCheckAll) const
+  {
+    return IsApplicable( shape, toCheckAll );
+  }
 
  private:
 
@@ -508,11 +536,22 @@ public:
    */
   bool compute(const Prism_3D::TPrismTopo& thePrism);
 
+  /*!
+   * \brief Compute the base face of a prism
+   */
+  bool computeBase(const Prism_3D::TPrismTopo& thePrism);
+
   /*!
    * \brief Compute 2D mesh on walls FACEs of a prism
    */
   bool computeWalls(const Prism_3D::TPrismTopo& thePrism);
 
+  /*!
+   * \brief Create artificial wall quads for vertical projection between the outer and inner walls
+   */
+  void makeQuadsForOutInProjection( const Prism_3D::TPrismTopo&      thePrism,
+                                    std::multimap< int, int >&       wgt2quad,
+                                    std::map< int, FaceQuadStruct >& iW2oiQuads);
   /*!
    * \brief Returns a source EDGE of propagation to a given EDGE
    */
@@ -545,6 +584,11 @@ public:
    */
   bool isSimpleBottom( const Prism_3D::TPrismTopo& thePrism );
 
+  /*!
+   * \brief Defines if all "vertical" EDGEs are straight
+   */
+  bool allVerticalEdgesStraight( const Prism_3D::TPrismTopo& thePrism );
+
   /*!
    * \brief Project mesh faces from a source FACE of one prism to
    *        a source FACE of another prism
@@ -578,6 +622,7 @@ private:
 
   StdMeshers_PrismAsBlock myBlock;
   SMESH_MesherHelper*     myHelper;
+  SMESH_subMesh*          myPrevBottomSM;
 
   std::vector<gp_XYZ>     myShapeXYZ; // point on each sub-shape of the block
 
index a0164ef01e073439895d4a43bc8d8c62b6ab092f..924eba9bf39bba644c6748ec5d0093e8ed5c9b56 100644 (file)
@@ -28,6 +28,7 @@
 #include "StdMeshers_ProjectionUtils.hxx"
 
 #include "SMDS_EdgePosition.hxx"
+#include "SMDS_FacePosition.hxx"
 #include "SMESHDS_Mesh.hxx"
 #include "SMESH_Algo.hxx"
 #include "SMESH_Block.hxx"
@@ -46,6 +47,7 @@
 #include "utilities.h"
 
 #include <BRepAdaptor_Surface.hxx>
+#include <BRepMesh_Delaun.hxx>
 #include <BRepTools.hxx>
 #include <BRepTools_WireExplorer.hxx>
 #include <BRep_Builder.hxx>
@@ -476,6 +478,26 @@ namespace {
     return !allBndEdges.empty();
   }
 
+  /*!
+   * \brief Convertor used in Delaunay constructor
+   */
+  struct SideVector2UVPtStructVec
+  {
+    std::vector< const UVPtStructVec* > _uvVecs;
+
+    SideVector2UVPtStructVec( const TSideVector& wires )
+    {
+      _uvVecs.resize( wires.size() );
+      for ( size_t i = 0; i < wires.size(); ++i )
+        _uvVecs[ i ] = & wires[i]->GetUVPtStruct();
+    }
+
+    operator const std::vector< const UVPtStructVec* > & () const
+    {
+      return _uvVecs;
+    }
+  };
+
 } // namespace
 
 //=======================================================================
@@ -679,7 +701,7 @@ bool StdMeshers_ProjectionUtils::FindSubShapeAssociation(const TopoDS_Shape& the
           RETURN_BAD_RESULT("edge2 does not belong to theShape2");
       }
       //
-      // Look for 2 corresponing faces:
+      // Look for 2 corresponding faces:
       //
       TopoDS_Shape F1, F2;
 
@@ -1098,6 +1120,11 @@ bool StdMeshers_ProjectionUtils::FindSubShapeAssociation(const TopoDS_Shape& the
         // take care of proper association of propagated edges
         bool same1 = edge1.IsSame( edges1.front() );
         bool same2 = edge2.IsSame( edges2.front() );
+        if ( !same1 && !same2 )
+        {
+          same1 = ( edges1.back().Orientation() == edge1.Orientation() );
+          same2 = ( edges2.back().Orientation() == edge2.Orientation() );
+        }
         if ( same1 != same2 )
         {
           reverseEdges(edges2, nbE);
@@ -2787,4 +2814,146 @@ namespace StdMeshers_ProjectionUtils
     }
     return true;
   }
-}
+
+  //================================================================================
+  /*!
+   * \brief triangulate the srcFace in 2D
+   *  \param [in] srcWires - boundary of the src FACE
+   */
+  //================================================================================
+
+  Morph::Morph(const TSideVector& srcWires):
+    _delaunay( srcWires, /*checkUV=*/true )
+  {
+    _srcSubMesh = srcWires[0]->GetMesh()->GetSubMesh( srcWires[0]->Face() );
+  }
+
+  //================================================================================
+  /*!
+   * \brief Move non-marked target nodes
+   *  \param [in,out] tgtHelper - helper
+   *  \param [in] tgtWires - boundary nodes of the target FACE; must be in the
+   *         same order as the nodes in srcWires given in the constructor
+   *  \param [in] src2tgtNodes - map of src -> tgt nodes
+   *  \param [in] moveAll - to move all nodes; if \c false, move only non-marked nodes
+   *  \return bool - Ok or not
+   */
+  //================================================================================
+
+  bool Morph::Perform(SMESH_MesherHelper&           tgtHelper,
+                      const TSideVector&            tgtWires,
+                      Handle(ShapeAnalysis_Surface) tgtSurface,
+                      const TNodeNodeMap&           src2tgtNodes,
+                      const bool                    moveAll)
+  {
+    // get tgt boundary points corresponding to src boundary nodes
+    size_t nbP = 0;
+    for ( size_t iW = 0; iW < tgtWires.size(); ++iW )
+      nbP += tgtWires[iW]->NbPoints() - 1; // 1st and last points coincide
+    if ( nbP != _delaunay.GetBndNodes().size() )
+      return false;
+
+    std::vector< gp_XY > tgtUV( nbP );
+    for ( size_t iW = 0, iP = 0; iW < tgtWires.size(); ++iW )
+    {
+      const UVPtStructVec& tgtPnt = tgtWires[iW]->GetUVPtStruct();
+      for ( int i = 0, nb = tgtPnt.size() - 1;  i < nb;  ++i, ++iP )
+      {
+        tgtUV[ iP ] = tgtPnt[i].UV();
+      }
+    }
+
+    SMESHDS_Mesh* tgtMesh = tgtHelper.GetMeshDS();
+    const SMDS_MeshNode *srcNode, *tgtNode;
+
+    // un-mark internal src nodes in order iterate them using _delaunay
+    int nbSrcNodes = 0;
+    SMDS_NodeIteratorPtr nIt = _srcSubMesh->GetSubMeshDS()->GetNodes();
+    if ( !nIt || !nIt->more() ) return true;
+    if ( moveAll )
+    {
+      nbSrcNodes = _srcSubMesh->GetSubMeshDS()->NbNodes();
+      while ( nIt->more() )
+        nIt->next()->setIsMarked( false );
+    }
+    else
+    {
+      while ( nIt->more() )
+        nbSrcNodes += int( !nIt->next()->isMarked() );
+    }
+
+    // Move tgt nodes
+
+    double bc[3]; // barycentric coordinates
+    int    nodeIDs[3]; // nodes of a delaunay triangle
+    const SMDS_FacePosition* pos;
+
+    _delaunay.InitTraversal( nbSrcNodes );
+
+    while (( srcNode = _delaunay.NextNode( bc, nodeIDs )))
+    {
+      // compute new coordinates for a corresponding tgt node
+      gp_XY uvNew( 0., 0. ), nodeUV;
+      for ( int i = 0; i < 3; ++i )
+        uvNew += bc[i] * tgtUV[ nodeIDs[i]];
+      gp_Pnt xyz = tgtSurface->Value( uvNew );
+
+      // find and move tgt node
+      TNodeNodeMap::const_iterator n2n = src2tgtNodes.find( srcNode );
+      if ( n2n == src2tgtNodes.end() ) continue;
+      tgtNode = n2n->second;
+      tgtMesh->MoveNode( tgtNode, xyz.X(), xyz.Y(), xyz.Z() );
+
+      if (( pos = dynamic_cast< const SMDS_FacePosition* >( tgtNode->GetPosition() )))
+        const_cast<SMDS_FacePosition*>( pos )->SetParameters( uvNew.X(), uvNew.Y() );
+
+      --nbSrcNodes;
+    }
+
+    return nbSrcNodes == 0;
+
+  } // Morph::Perform
+
+  //=======================================================================
+  //function : Delaunay
+  //purpose  : construct from face sides
+  //=======================================================================
+
+  Delaunay::Delaunay( const TSideVector& wires, bool checkUV ):
+    SMESH_Delaunay( SideVector2UVPtStructVec( wires ),
+                    TopoDS::Face( wires[0]->FaceHelper()->GetSubShape() ),
+                    wires[0]->FaceHelper()->GetSubShapeID() )
+  {
+    _wire = wires[0]; // keep a wire to assure _helper to keep alive
+    _helper = _wire->FaceHelper();
+    _checkUVPtr = checkUV ? & _checkUV : 0;
+  }
+
+  //=======================================================================
+  //function : Delaunay
+  //purpose  : construct from UVPtStructVec's
+  //=======================================================================
+
+  Delaunay::Delaunay( const std::vector< const UVPtStructVec* > & boundaryNodes,
+                      SMESH_MesherHelper&                         faceHelper,
+                      bool                                        checkUV):
+    SMESH_Delaunay( boundaryNodes,
+                    TopoDS::Face( faceHelper.GetSubShape() ),
+                    faceHelper.GetSubShapeID() )
+  {
+    _helper = & faceHelper;
+    _checkUVPtr = checkUV ? & _checkUV : 0;
+  }
+
+  //=======================================================================
+  //function : getNodeUV
+  //purpose  : 
+  //=======================================================================
+
+  gp_XY Delaunay::getNodeUV( const TopoDS_Face& face, const SMDS_MeshNode* node ) const
+  {
+    return _helper->GetNodeUV( face, node, 0, _checkUVPtr );
+  }
+  
+
+} // namespace StdMeshers_ProjectionUtils
index ced8febbd93fa0d5909844e70b5a39c901296daa..aa38284431b6bb048aa943f5aeeef368792cd499 100644 (file)
 #include "SMESH_StdMeshers.hxx"
 
 #include "SMDS_MeshElement.hxx"
+#include "SMESH_Delaunay.hxx"
+#include "StdMeshers_FaceSide.hxx"
 
+#include <ShapeAnalysis_Surface.hxx>
 #include <TopTools_DataMapOfShapeShape.hxx>
-#include <TopTools_IndexedMapOfShape.hxx>
 #include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
+#include <TopTools_IndexedMapOfShape.hxx>
 #include <TopoDS_Edge.hxx>
 #include <TopoDS_Face.hxx>
 #include <TopoDS_Vertex.hxx>
@@ -51,6 +54,7 @@ class SMESH_Mesh;
 class SMESH_subMesh;
 class TopoDS_Shape;
 
+//-----------------------------------------------------------------------------------------
 /*!
  * \brief Struct used instead of a sole TopTools_DataMapOfShapeShape to avoid
  *        problems with bidirectional bindings
@@ -91,6 +95,7 @@ namespace StdMeshers_ProjectionUtils
                    TIDCompare>                                 TNodeNodeMap;
 
 
+  //-----------------------------------------------------------------------------------------
   /*!
    * \brief Finds transformation between two sets of 2D points using
    *        a least square approximation
@@ -111,6 +116,7 @@ namespace StdMeshers_ProjectionUtils
 
     bool IsIdentity() const { return ( _trsf.Form() == gp_Identity ); }
   };
+  //-----------------------------------------------------------------------------------------
   /*!
    * \brief Finds transformation between two sets of 3D points using
    *        a least square approximation
@@ -136,6 +142,56 @@ namespace StdMeshers_ProjectionUtils
     bool Invert();
   };
 
+  //-----------------------------------------------------------------------------------------
+  /*!
+   * \brief Create a Delaunay triangulation of nodes on a face boundary
+   *        and provide exploration of nodes shared by elements lying on
+   *        the face. For a returned node, also return a Delaunay triangle
+   *        the node lies in and its Barycentric Coordinates within the triangle.
+   *        Only non-marked nodes are visited.
+   *
+   * The main methods are defined in ../SMESHUtils/SMESH_Delaunay.hxx
+   */
+  class Delaunay : public SMESH_Delaunay
+  {
+  public:
+
+    Delaunay( const TSideVector& wires, bool checkUV = false );
+
+    Delaunay( const std::vector< const UVPtStructVec* > & boundaryNodes,
+              SMESH_MesherHelper&                         faceHelper,
+              bool                                        checkUV = false);
+
+  protected:
+    virtual gp_XY getNodeUV( const TopoDS_Face& face, const SMDS_MeshNode* node ) const;
+
+  private:
+    SMESH_MesherHelper*    _helper;
+    StdMeshers_FaceSidePtr _wire;
+    bool                  *_checkUVPtr, _checkUV;
+  };
+  typedef boost::shared_ptr< Delaunay > DelaunayPtr;
+
+  //-----------------------------------------------------------------------------------------
+  /*!
+   * \brief Morph mesh on the target FACE to lie within FACE boundary w/o distortion
+   */
+  class Morph
+  {
+    Delaunay       _delaunay;
+    SMESH_subMesh* _srcSubMesh;
+  public:
+
+    Morph(const TSideVector& srcWires);
+
+    bool Perform(SMESH_MesherHelper&           tgtHelper,
+                 const TSideVector&            tgtWires,
+                 Handle(ShapeAnalysis_Surface) tgtSurface,
+                 const TNodeNodeMap&           src2tgtNodes,
+                 const bool                    moveAll);
+  };
+
+  //-----------------------------------------------------------------------------------------
   /*!
    * \brief Looks for association of all sub-shapes of two shapes
    * \param theShape1 - shape 1
index eeb20f00981b187845326a9f89555d493339c052..64ce054c5d9d6a2385c97e980f0d8e6de654156e 100644 (file)
@@ -1133,7 +1133,7 @@ namespace {
   {
     SMESH_subMesh* faceSM = helper.GetMesh()->GetSubMesh( helper.GetSubShape() );
 
-    if ( helper.IsDistorted2D( faceSM, /*checkUV=*/true ))
+    //if ( helper.IsDistorted2D( faceSM, /*checkUV=*/true ))
     {
       SMESH_MeshEditor editor( helper.GetMesh() );
       SMESHDS_SubMesh* smDS = faceSM->GetSubMeshDS();
@@ -1179,240 +1179,6 @@ namespace {
     return true;
   }
 
-  typedef list< pair< const SMDS_MeshNode*, const BRepMesh_Triangle* > > TNodeTriaList;
-
-  //================================================================================
-  /*!
-   * \brief Add in-FACE nodes surrounding a given node to a queue
-   */
-  //================================================================================
-
-  void addCloseNodes( const SMDS_MeshNode*     srcNode,
-                      const BRepMesh_Triangle* bmTria,
-                      const int                srcFaceID,
-                      TNodeTriaList &          noTriQueue )
-  {
-    // find in-FACE nodes
-    SMDS_ElemIteratorPtr elems = srcNode->GetInverseElementIterator(SMDSAbs_Face);
-    while ( elems->more() )
-    {
-      const SMDS_MeshElement* elem = elems->next();
-      if ( elem->getshapeId() == srcFaceID )
-      {
-        for ( int i = 0, nb = elem->NbNodes(); i < nb; ++i )
-        {
-          const SMDS_MeshNode* n = elem->GetNode( i );
-          if ( !n->isMarked() )
-            noTriQueue.push_back( make_pair( n, bmTria ));
-        }
-      }
-    }
-  }
-
-  //================================================================================
-  /*!
-   * \brief Find a delauney triangle containing a given 2D point and return
-   *        barycentric coordinates within the found triangle
-   */
-  //================================================================================
-
-  const BRepMesh_Triangle* findTriangle( const gp_XY&                            uv,
-                                         const BRepMesh_Triangle*                bmTria,
-                                         Handle(BRepMesh_DataStructureOfDelaun)& triaDS,
-                                         double                                  bc[3] )
-  {
-    int   nodeIDs[3];
-    gp_XY nodeUVs[3];
-    int   linkIDs[3];
-    Standard_Boolean ori[3];
-
-    while ( bmTria )
-    {
-      // check bmTria
-
-      triaDS->ElementNodes( *bmTria, nodeIDs );
-      nodeUVs[0] = triaDS->GetNode( nodeIDs[0] ).Coord();
-      nodeUVs[1] = triaDS->GetNode( nodeIDs[1] ).Coord();
-      nodeUVs[2] = triaDS->GetNode( nodeIDs[2] ).Coord();
-
-      SMESH_MeshAlgos::GetBarycentricCoords( uv,
-                                             nodeUVs[0], nodeUVs[1], nodeUVs[2],
-                                             bc[0], bc[1] );
-      if ( bc[0] >= 0 && bc[1] >= 0 && bc[0] + bc[1] <= 1 )
-      {
-        bc[2] = 1 - bc[0] - bc[1];
-        return bmTria;
-      }
-
-      // look for a neighbor triangle, which is adjacent to a link intersected
-      // by a segment( triangle center -> uv )
-
-      gp_XY gc = ( nodeUVs[0] + nodeUVs[1] + nodeUVs[2] ) / 3.;
-      gp_XY seg = uv - gc;
-
-      bmTria->Edges( linkIDs, ori );
-      int triaID = triaDS->IndexOf( *bmTria );
-      bmTria = 0;
-
-      for ( int i = 0; i < 3; ++i )
-      {
-        const BRepMesh_PairOfIndex & triIDs = triaDS->ElementsConnectedTo( linkIDs[i] );
-        if ( triIDs.Extent() < 2 )
-          continue; // no neighbor triangle
-
-        // check if a link intersects gc2uv
-        const BRepMesh_Edge & link = triaDS->GetLink( linkIDs[i] );
-        const BRepMesh_Vertex & n1 = triaDS->GetNode( link.FirstNode() );
-        const BRepMesh_Vertex & n2 = triaDS->GetNode( link.LastNode() );
-        gp_XY uv1 = n1.Coord();
-        gp_XY lin = n2.Coord() - uv1; // link direction
-
-        double crossSegLin = seg ^ lin;
-        if ( Abs( crossSegLin ) < std::numeric_limits<double>::min() )
-          continue; // parallel
-
-        double uSeg = ( uv1 - gc ) ^ lin / crossSegLin;
-        if ( 0. <= uSeg && uSeg <= 1. )
-        {
-          bmTria = & triaDS->GetElement( triIDs.Index( 1 + ( triIDs.Index(1) == triaID )));
-          break;
-        }
-      }
-    }
-    return bmTria;
-  }
-
-  //================================================================================
-  /*!
-   * \brief Morph mesh on the target face to lie within FACE boundary w/o distortion
-   *
-   * algo:
-   * - make a CDT on the src FACE
-   * - find a triangle containing a src node and get its barycentric coordinates
-   * - move the node to a point with the same barycentric coordinates in a corresponding
-   *   tgt triangle
-   */
-  //================================================================================
-
-  bool morph( SMESH_MesherHelper&             tgtHelper,
-              const TopoDS_Face&              tgtFace,
-              const TopoDS_Face&              srcFace,
-              const TSideVector&              tgtWires,
-              const TSideVector&              srcWires,
-              const TAssocTool::TNodeNodeMap& src2tgtNodes )
-  {
-    if ( srcWires.size() != tgtWires.size() ) return false;
-    if ( srcWires.size() == 1 ) return false; // tmp
-
-    // count boundary points
-    int iP = 1, nbP = 0;
-    for ( size_t iW = 0; iW < srcWires.size(); ++iW )
-      nbP += srcWires[iW]->NbPoints() - 1; // 1st and last points coincide
-
-    // fill boundary points
-    BRepMesh::Array1OfVertexOfDelaun srcVert( 1, 1 + nbP ), tgtVert( 1, 1 + nbP );
-    vector< const SMDS_MeshNode* > bndSrcNodes( nbP + 1 ); bndSrcNodes[0] = 0;
-    BRepMesh_Vertex v( 0, 0, BRepMesh_Frontier );
-    for ( size_t iW = 0; iW < srcWires.size(); ++iW )
-    {
-      const UVPtStructVec& srcPnt = srcWires[iW]->GetUVPtStruct();
-      const UVPtStructVec& tgtPnt = tgtWires[iW]->GetUVPtStruct();
-      if ( srcPnt.size() != tgtPnt.size() ) return false;
-
-      for ( int i = 0, nb = srcPnt.size() - 1;  i < nb;  ++i, ++iP )
-      {
-        bndSrcNodes[ iP ]  = srcPnt[i].node;
-        srcPnt[i].node->setIsMarked( true );
-
-        v.ChangeCoord() = srcPnt[i].UV();
-        srcVert( iP )   = v;
-        v.ChangeCoord() = tgtPnt[i].UV();
-        tgtVert( iP )   = v;
-      }
-    }
-    // triangulate the srcFace in 2D
-    BRepMesh_Delaun delauney( srcVert );
-    Handle(BRepMesh_DataStructureOfDelaun) triaDS = delauney.Result();
-
-    Handle(ShapeAnalysis_Surface) tgtSurface = tgtHelper.GetSurface( tgtFace );
-    SMESHDS_Mesh* srcMesh = srcWires[0]->GetMesh()->GetMeshDS();
-    SMESHDS_Mesh* tgtMesh = tgtHelper.GetMeshDS();
-    const SMDS_MeshNode *srcNode, *tgtNode;
-    const BRepMesh_Triangle *bmTria;
-
-    // un-mark internal src nodes; later we will mark moved nodes
-    SMDS_NodeIteratorPtr nIt = srcMesh->MeshElements( srcFace )->GetNodes();
-    if ( !nIt || !nIt->more() ) return true;
-    while ( nIt->more() )
-      ( srcNode = nIt->next() )->setIsMarked( false );
-
-    // initialize a queue of nodes with starting triangles
-    const int srcFaceID = srcNode->getshapeId();
-    TNodeTriaList noTriQueue;
-    size_t iBndSrcN = 1;
-    for ( ; iBndSrcN < bndSrcNodes.size() &&  noTriQueue.empty();  ++iBndSrcN )
-    {
-      // get a triangle
-      const BRepMesh::ListOfInteger & linkIds = triaDS->LinksConnectedTo( iBndSrcN );
-      const BRepMesh_PairOfIndex &    triaIds = triaDS->ElementsConnectedTo( linkIds.First() );
-      const BRepMesh_Triangle&           tria = triaDS->GetElement( triaIds.Index(1) );
-
-      addCloseNodes( bndSrcNodes[ iBndSrcN ], &tria, srcFaceID, noTriQueue );
-    }
-
-    // Move tgt nodes
-
-    double bc[3]; // barycentric coordinates
-    int    nodeIDs[3];
-    bool   checkUV = true;
-    const SMDS_FacePosition* pos;
-
-    while ( !noTriQueue.empty() )
-    {
-      srcNode = noTriQueue.front().first;
-      bmTria  = noTriQueue.front().second;
-      noTriQueue.pop_front();
-      if ( srcNode->isMarked() )
-        continue;
-      srcNode->setIsMarked( true );
-
-      // find a delauney triangle containing the src node
-      gp_XY uv = tgtHelper.GetNodeUV( srcFace, srcNode, NULL, &checkUV );
-      bmTria = findTriangle( uv, bmTria, triaDS, bc );
-      if ( !bmTria )
-        continue;
-
-      // compute new coordinates for a corresponding tgt node
-      gp_XY uvNew( 0., 0. ), nodeUV;
-      triaDS->ElementNodes( *bmTria, nodeIDs );
-      for ( int i = 0; i < 3; ++i )
-        uvNew += bc[i] * tgtVert( nodeIDs[i]).Coord();
-      gp_Pnt xyz = tgtSurface->Value( uvNew );
-
-      // find and move tgt node
-      TAssocTool::TNodeNodeMap::const_iterator n2n = src2tgtNodes.find( srcNode );
-      if ( n2n == src2tgtNodes.end() ) continue;
-      tgtNode = n2n->second;
-      tgtMesh->MoveNode( tgtNode, xyz.X(), xyz.Y(), xyz.Z() );
-
-      if (( pos = dynamic_cast< const SMDS_FacePosition* >( tgtNode->GetPosition() )))
-        const_cast<SMDS_FacePosition*>( pos )->SetParameters( uvNew.X(), uvNew.Y() );
-
-      addCloseNodes( srcNode, bmTria, srcFaceID, noTriQueue );
-
-      // assure that all src nodes are visited
-      for ( ; iBndSrcN < bndSrcNodes.size() &&  noTriQueue.empty();  ++iBndSrcN )
-      {
-        const BRepMesh::ListOfInteger & linkIds = triaDS->LinksConnectedTo( iBndSrcN );
-        const BRepMesh_PairOfIndex &    triaIds = triaDS->ElementsConnectedTo( linkIds.First() );
-        const BRepMesh_Triangle&           tria = triaDS->GetElement( triaIds.Index(1) );
-        addCloseNodes( bndSrcNodes[ iBndSrcN ], &tria, srcFaceID, noTriQueue );
-      }
-    }
-
-    return true;
-  }
-
   //=======================================================================
   /*
    * Set initial association of VERTEXes for the case of projection
@@ -1614,11 +1380,12 @@ bool StdMeshers_Projection_2D::Compute(SMESH_Mesh& theMesh, const TopoDS_Shape&
       TopoDS_Edge srcE1 = srcEdges.front(), tgtE1 = tgtEdges.front();
       TopoDS_Shape srcE1bis = shape2ShapeMap( tgtE1 );
       reverse = ( ! srcE1.IsSame( srcE1bis ));
-      if ( reverse &&
-           //_sourceHypo->HasVertexAssociation() &&
+      if ( ( reverse || srcE1.Orientation() != srcE1bis.Orientation() ) &&
            nbEdgesInWires.front() > 2 &&
            helper.IsRealSeam( tgtEdges.front() ))
       {
+        if ( srcE1.Orientation() != srcE1bis.Orientation() )
+          reverse = true;
         // projection to a face with seam EDGE; pb is that GetOrderedEdges()
         // always puts a seam EDGE first (if possible) and as a result
         // we can't use only theReverse flag to correctly associate source
@@ -1933,7 +1700,9 @@ bool StdMeshers_Projection_2D::Compute(SMESH_Mesh& theMesh, const TopoDS_Shape&
     // ----------------------------------------------------------------
     if ( helper.IsDistorted2D( tgtSubMesh, /*checkUV=*/false, &helper ))
     {
-      morph( helper, tgtFace, srcFace, tgtWires, srcWires, _src2tgtNodes );
+      TAssocTool::Morph morph( srcWires );
+      morph.Perform( helper, tgtWires, helper.GetSurface( tgtFace ),
+                     _src2tgtNodes, /*moveAll=*/true );
 
       if ( !fixDistortedFaces( helper, tgtWires ))
         return error("Invalid mesh generated");
index b1a05f9ac02da495bc3ce449d340fa6137695fff..008ca7429f7b2ca94af6debfb30b933b553f137c 100644 (file)
@@ -57,6 +57,10 @@ public:
    */
   virtual void SetEventListener(SMESH_subMesh* whenSetToSubMesh);
   
+  virtual bool IsApplicableToShape(const TopoDS_Shape & shape, bool toCheckAll) const
+  {
+    return IsApplicable( shape, toCheckAll );
+  }
   static bool IsApplicable(const TopoDS_Shape & aShape, bool toCheckAll);
 
  protected:
index 58a3364c77f53b4e8e0d01c0a7dcba1001df65ec..43a62debad005690b0203d9ceb2f18da15245d07 100644 (file)
@@ -53,6 +53,10 @@ class STDMESHERS_EXPORT StdMeshers_QuadFromMedialAxis_1D2D: public StdMeshers_Qu
 
   virtual void SetEventListener(SMESH_subMesh* subMesh);
 
+  virtual bool IsApplicableToShape(const TopoDS_Shape & shape, bool toCheckAll) const
+  {
+    return IsApplicable( shape, toCheckAll );
+  }
   static bool IsApplicable(const TopoDS_Shape & aShape, bool toCheckAll);
 
   class Algo1D;
index ef472e49aedb00e20e3801668428cf71439ef8d4..994089cfe4e7fe09482f3102aa8eb5ea3e942894 100644 (file)
@@ -51,7 +51,6 @@
 #include <Geom_Surface.hxx>
 #include <NCollection_DefineArray2.hxx>
 #include <Precision.hxx>
-#include <Quantity_Parameter.hxx>
 #include <TColStd_SequenceOfInteger.hxx>
 #include <TColStd_SequenceOfReal.hxx>
 #include <TColgp_SequenceOfXY.hxx>
 #include "utilities.h"
 #include "Utils_ExceptHandlers.hxx"
 
-#ifndef StdMeshers_Array2OfNode_HeaderFile
-#define StdMeshers_Array2OfNode_HeaderFile
-typedef const SMDS_MeshNode* SMDS_MeshNodePtr;
-typedef NCollection_Array2<SMDS_MeshNodePtr> StdMeshers_Array2OfNode;
-#endif
+#include <boost/container/flat_set.hpp>
 
-using namespace std;
+typedef NCollection_Array2<const SMDS_MeshNode*> StdMeshers_Array2OfNode;
 
 typedef gp_XY gp_UV;
 typedef SMESH_Comment TComm;
 
+using namespace std;
+
 //=============================================================================
 /*!
  *
@@ -1011,14 +1008,14 @@ bool StdMeshers_Quadrangle_2D::IsApplicable( const TopoDS_Shape & aShape, bool t
       continue;
     }
 
-    int nbNoDegenEdges = 0;
+    int nbNoDegenEdges = 0, totalNbEdges = 0;
     TopExp_Explorer eExp( aFace, TopAbs_EDGE );
-    for ( ; eExp.More() && nbNoDegenEdges < 3; eExp.Next() ) {
+    for ( ; eExp.More() && nbNoDegenEdges < 3; eExp.Next(), ++totalNbEdges ) {
       if ( !SMESH_Algo::isDegenerated( TopoDS::Edge( eExp.Current() )))
         ++nbNoDegenEdges;
     }
-    if ( toCheckAll  && nbNoDegenEdges <  3 ) return false;
-    if ( !toCheckAll && nbNoDegenEdges >= 3 ) return true;
+    if (  toCheckAll && ( totalNbEdges <  4 && nbNoDegenEdges <  3 )) return false;
+    if ( !toCheckAll && ( totalNbEdges >= 4 || nbNoDegenEdges >= 3 )) return true;
   }
   return ( toCheckAll && nbFoundFaces != 0 );
 }
@@ -1140,7 +1137,7 @@ FaceQuadStruct::Ptr StdMeshers_Quadrangle_2D::CheckNbEdges(SMESH_Mesh &
             }
           }
         }
-        else
+        else //if ( !myHelper || !myHelper->IsRealSeam( edge ))
         {
           sideEdges.push_back( edge );
         }
@@ -3896,171 +3893,177 @@ void StdMeshers_Quadrangle_2D::smooth (FaceQuadStruct::Ptr quad)
   {
     // "smooth" by computing node positions using 3D TFI and further projection
 
-    int nbhoriz  = quad->iSize;
-    int nbvertic = quad->jSize;
+    list< FaceQuadStruct::Ptr >::iterator q = myQuadList.begin();
+    for ( ; q != myQuadList.end() ; ++q )
+    {
+      quad = *q;
+      int nbhoriz  = quad->iSize;
+      int nbvertic = quad->jSize;
 
-    SMESH_TNodeXYZ a0( quad->UVPt( 0,         0          ).node );
-    SMESH_TNodeXYZ a1( quad->UVPt( nbhoriz-1, 0          ).node );
-    SMESH_TNodeXYZ a2( quad->UVPt( nbhoriz-1, nbvertic-1 ).node );
-    SMESH_TNodeXYZ a3( quad->UVPt( 0,         nbvertic-1 ).node );
+      SMESH_TNodeXYZ a0( quad->UVPt( 0,         0          ).node );
+      SMESH_TNodeXYZ a1( quad->UVPt( nbhoriz-1, 0          ).node );
+      SMESH_TNodeXYZ a2( quad->UVPt( nbhoriz-1, nbvertic-1 ).node );
+      SMESH_TNodeXYZ a3( quad->UVPt( 0,         nbvertic-1 ).node );
 
-    for (int i = 1; i < nbhoriz-1; i++)
-    {
-      SMESH_TNodeXYZ p0( quad->UVPt( i, 0          ).node );
-      SMESH_TNodeXYZ p2( quad->UVPt( i, nbvertic-1 ).node );
-      for (int j = 1; j < nbvertic-1; j++)
+      for (int i = 1; i < nbhoriz-1; i++)
       {
-        SMESH_TNodeXYZ p1( quad->UVPt( nbhoriz-1, j ).node );
-        SMESH_TNodeXYZ p3( quad->UVPt( 0,         j ).node );
+        SMESH_TNodeXYZ p0( quad->UVPt( i, 0          ).node );
+        SMESH_TNodeXYZ p2( quad->UVPt( i, nbvertic-1 ).node );
+        for (int j = 1; j < nbvertic-1; j++)
+        {
+          SMESH_TNodeXYZ p1( quad->UVPt( nbhoriz-1, j ).node );
+          SMESH_TNodeXYZ p3( quad->UVPt( 0,         j ).node );
 
-        UVPtStruct& uvp = quad->UVPt( i, j );
+          UVPtStruct& uvp = quad->UVPt( i, j );
 
-        gp_Pnt    p = myHelper->calcTFI(uvp.x,uvp.y, a0,a1,a2,a3, p0,p1,p2,p3);
-        gp_Pnt2d uv = surface->NextValueOfUV( uvp.UV(), p, 10*tol );
-        gp_Pnt pnew = surface->Value( uv );
+          gp_Pnt    p = myHelper->calcTFI(uvp.x,uvp.y, a0,a1,a2,a3, p0,p1,p2,p3);
+          gp_Pnt2d uv = surface->NextValueOfUV( uvp.UV(), p, 10*tol );
+          gp_Pnt pnew = surface->Value( uv );
 
-        meshDS->MoveNode( uvp.node, pnew.X(), pnew.Y(), pnew.Z() );
-        uvp.u = uv.X();
-        uvp.v = uv.Y();
+          meshDS->MoveNode( uvp.node, pnew.X(), pnew.Y(), pnew.Z() );
+          uvp.u = uv.X();
+          uvp.v = uv.Y();
+        }
       }
     }
-    return;
   }
+  else
+  {
+    // Get nodes to smooth
 
-  // Get nodes to smooth
-
-  typedef map< const SMDS_MeshNode*, TSmoothNode, TIDCompare > TNo2SmooNoMap;
-  TNo2SmooNoMap smooNoMap;
+    typedef map< const SMDS_MeshNode*, TSmoothNode, TIDCompare > TNo2SmooNoMap;
+    TNo2SmooNoMap smooNoMap;
 
-  // fixed nodes
-  set< const SMDS_MeshNode* > fixedNodes;
-  for ( size_t i = 0; i < myForcedPnts.size(); ++i )
-  {
-    fixedNodes.insert( myForcedPnts[i].node );
-    if ( myForcedPnts[i].node->getshapeId() != myHelper->GetSubShapeID() )
+    // fixed nodes
+    boost::container::flat_set< const SMDS_MeshNode* > fixedNodes;
+    for ( size_t i = 0; i < myForcedPnts.size(); ++i )
     {
-      TSmoothNode & sNode = smooNoMap[ myForcedPnts[i].node ];
-      sNode._uv  = myForcedPnts[i].uv;
-      sNode._xyz = SMESH_TNodeXYZ( myForcedPnts[i].node );
+      fixedNodes.insert( myForcedPnts[i].node );
+      if ( myForcedPnts[i].node->getshapeId() != myHelper->GetSubShapeID() )
+      {
+        TSmoothNode & sNode = smooNoMap[ myForcedPnts[i].node ];
+        sNode._uv  = myForcedPnts[i].uv;
+        sNode._xyz = SMESH_TNodeXYZ( myForcedPnts[i].node );
+      }
     }
-  }
-  SMESHDS_SubMesh* fSubMesh = meshDS->MeshElements( quad->face );
-  SMDS_NodeIteratorPtr  nIt = fSubMesh->GetNodes();
-  while ( nIt->more() ) // loop on nodes bound to a FACE
-  {
-    const SMDS_MeshNode* node = nIt->next();
-    TSmoothNode & sNode = smooNoMap[ node ];
-    sNode._uv  = myHelper->GetNodeUV( quad->face, node );
-    sNode._xyz = SMESH_TNodeXYZ( node );
-    if ( fixedNodes.count( node ))
-      continue; // fixed - no triangles
-
-    // set sNode._triangles
-    SMDS_ElemIteratorPtr fIt = node->GetInverseElementIterator( SMDSAbs_Face );
-    while ( fIt->more() )
+    SMESHDS_SubMesh* fSubMesh = meshDS->MeshElements( quad->face );
+    SMDS_NodeIteratorPtr  nIt = fSubMesh->GetNodes();
+    while ( nIt->more() ) // loop on nodes bound to a FACE
     {
-      const SMDS_MeshElement* face = fIt->next();
-      const int nbN     = face->NbCornerNodes();
-      const int nInd    = face->GetNodeIndex( node );
-      const int prevInd = myHelper->WrapIndex( nInd - 1, nbN );
-      const int nextInd = myHelper->WrapIndex( nInd + 1, nbN );
-      const SMDS_MeshNode* prevNode = face->GetNode( prevInd );
-      const SMDS_MeshNode* nextNode = face->GetNode( nextInd );
-      sNode._triangles.push_back( TTriangle( & smooNoMap[ prevNode ],
-                                             & smooNoMap[ nextNode ]));
-    }
-  }
-  // set _uv of smooth nodes on FACE boundary
-  set< StdMeshers_FaceSide* > sidesOnEdge;
-  list< FaceQuadStruct::Ptr >::iterator q = myQuadList.begin();
-  for ( ; q != myQuadList.end() ; ++q )
-    for ( size_t i = 0; i < (*q)->side.size(); ++i )
-      if ( ! (*q)->side[i].grid->Edge(0).IsNull() &&
-           //(*q)->nbNodeOut( i ) == 0 &&
-           sidesOnEdge.insert( (*q)->side[i].grid.get() ).second )
+      const SMDS_MeshNode* node = nIt->next();
+      TSmoothNode & sNode = smooNoMap[ node ];
+      sNode._uv  = myHelper->GetNodeUV( quad->face, node );
+      sNode._xyz = SMESH_TNodeXYZ( node );
+      if ( fixedNodes.count( node ))
+        continue; // fixed - no triangles
+
+      // set sNode._triangles
+      SMDS_ElemIteratorPtr fIt = node->GetInverseElementIterator( SMDSAbs_Face );
+      while ( fIt->more() )
       {
-        const vector<UVPtStruct>& uvVec = (*q)->side[i].grid->GetUVPtStruct();
-        for ( unsigned j = 0; j < uvVec.size(); ++j )
+        const SMDS_MeshElement* face = fIt->next();
+        const int nbN     = face->NbCornerNodes();
+        const int nInd    = face->GetNodeIndex( node );
+        const int prevInd = myHelper->WrapIndex( nInd - 1, nbN );
+        const int nextInd = myHelper->WrapIndex( nInd + 1, nbN );
+        const SMDS_MeshNode* prevNode = face->GetNode( prevInd );
+        const SMDS_MeshNode* nextNode = face->GetNode( nextInd );
+        sNode._triangles.push_back( TTriangle( & smooNoMap[ prevNode ],
+                                               & smooNoMap[ nextNode ]));
+      }
+    }
+    // set _uv of smooth nodes on FACE boundary
+    set< StdMeshers_FaceSide* > sidesOnEdge;
+    list< FaceQuadStruct::Ptr >::iterator q = myQuadList.begin();
+    for ( ; q != myQuadList.end() ; ++q )
+      for ( size_t i = 0; i < (*q)->side.size(); ++i )
+        if ( ! (*q)->side[i].grid->Edge(0).IsNull() &&
+             //(*q)->nbNodeOut( i ) == 0 &&
+             sidesOnEdge.insert( (*q)->side[i].grid.get() ).second )
         {
-          TSmoothNode & sNode = smooNoMap[ uvVec[j].node ];
-          sNode._uv  = uvVec[j].UV();
-          sNode._xyz = SMESH_TNodeXYZ( uvVec[j].node );
+          const vector<UVPtStruct>& uvVec = (*q)->side[i].grid->GetUVPtStruct();
+          for ( unsigned j = 0; j < uvVec.size(); ++j )
+          {
+            TSmoothNode & sNode = smooNoMap[ uvVec[j].node ];
+            sNode._uv  = uvVec[j].UV();
+            sNode._xyz = SMESH_TNodeXYZ( uvVec[j].node );
+          }
         }
-      }
 
-  // define reference orientation in 2D
-  TNo2SmooNoMap::iterator n2sn = smooNoMap.begin();
-  for ( ; n2sn != smooNoMap.end(); ++n2sn )
-    if ( !n2sn->second._triangles.empty() )
-      break;
-  if ( n2sn == smooNoMap.end() ) return;
-  const TSmoothNode & sampleNode = n2sn->second;
-  const bool refForward = ( sampleNode._triangles[0].IsForward( sampleNode._uv ));
+    // define reference orientation in 2D
+    TNo2SmooNoMap::iterator n2sn = smooNoMap.begin();
+    for ( ; n2sn != smooNoMap.end(); ++n2sn )
+      if ( !n2sn->second._triangles.empty() )
+        break;
+    if ( n2sn == smooNoMap.end() ) return;
+    const TSmoothNode & sampleNode = n2sn->second;
+    const bool refForward = ( sampleNode._triangles[0].IsForward( sampleNode._uv ));
 
-  // Smoothing
+    // Smoothing
 
-  for ( int iLoop = 0; iLoop < 5; ++iLoop )
-  {
-    for ( n2sn = smooNoMap.begin(); n2sn != smooNoMap.end(); ++n2sn )
+    for ( int iLoop = 0; iLoop < 5; ++iLoop )
     {
-      TSmoothNode& sNode = n2sn->second;
-      if ( sNode._triangles.empty() )
-        continue; // not movable node
+      for ( n2sn = smooNoMap.begin(); n2sn != smooNoMap.end(); ++n2sn )
+      {
+        TSmoothNode& sNode = n2sn->second;
+        if ( sNode._triangles.empty() )
+          continue; // not movable node
 
-      gp_XY newUV;
-      bool isValid = false;
-      bool use3D   = ( iLoop > 2 ); // 3 loops in 2D and 2, in 3D
+        gp_XY newUV;
+        bool isValid = false;
+        bool use3D   = ( iLoop > 2 ); // 3 loops in 2D and 2, in 3D
 
-      if ( use3D )
-      {
-        // compute a new XYZ
-        gp_XYZ newXYZ (0,0,0);
-        for ( size_t i = 0; i < sNode._triangles.size(); ++i )
-          newXYZ += sNode._triangles[i]._n1->_xyz;
-        newXYZ /= sNode._triangles.size();
-
-        // compute a new UV by projection
-        newUV = surface->NextValueOfUV( sNode._uv, newXYZ, 10*tol ).XY();
-
-        // check validity of the newUV
-        for ( size_t i = 0; i < sNode._triangles.size() && isValid; ++i )
-          isValid = ( sNode._triangles[i].IsForward( newUV ) == refForward );
-      }
-      if ( !isValid )
-      {
-        // compute a new UV by averaging
-        newUV.SetCoord(0.,0.);
-        for ( unsigned i = 0; i < sNode._triangles.size(); ++i )
-          newUV += sNode._triangles[i]._n1->_uv;
-        newUV /= sNode._triangles.size();
-
-        // check validity of the newUV
-        isValid = true;
-        for ( unsigned i = 0; i < sNode._triangles.size() && isValid; ++i )
-          isValid = ( sNode._triangles[i].IsForward( newUV ) == refForward );
-      }
-      if ( isValid )
-      {
-        sNode._uv = newUV;
-        sNode._xyz = surface->Value( newUV ).XYZ();
+        if ( use3D )
+        {
+          // compute a new XYZ
+          gp_XYZ newXYZ (0,0,0);
+          for ( size_t i = 0; i < sNode._triangles.size(); ++i )
+            newXYZ += sNode._triangles[i]._n1->_xyz;
+          newXYZ /= sNode._triangles.size();
+
+          // compute a new UV by projection
+          newUV = surface->NextValueOfUV( sNode._uv, newXYZ, 10*tol ).XY();
+
+          // check validity of the newUV
+          for ( size_t i = 0; i < sNode._triangles.size() && isValid; ++i )
+            isValid = ( sNode._triangles[i].IsForward( newUV ) == refForward );
+        }
+        if ( !isValid )
+        {
+          // compute a new UV by averaging
+          newUV.SetCoord(0.,0.);
+          for ( unsigned i = 0; i < sNode._triangles.size(); ++i )
+            newUV += sNode._triangles[i]._n1->_uv;
+          newUV /= sNode._triangles.size();
+
+          // check validity of the newUV
+          isValid = true;
+          for ( unsigned i = 0; i < sNode._triangles.size() && isValid; ++i )
+            isValid = ( sNode._triangles[i].IsForward( newUV ) == refForward );
+        }
+        if ( isValid )
+        {
+          sNode._uv = newUV;
+          sNode._xyz = surface->Value( newUV ).XYZ();
+        }
       }
     }
-  }
 
-  // Set new XYZ to the smoothed nodes
+    // Set new XYZ to the smoothed nodes
 
-  for ( n2sn = smooNoMap.begin(); n2sn != smooNoMap.end(); ++n2sn )
-  {
-    TSmoothNode& sNode = n2sn->second;
-    if ( sNode._triangles.empty() )
-      continue; // not movable node
+    for ( n2sn = smooNoMap.begin(); n2sn != smooNoMap.end(); ++n2sn )
+    {
+      TSmoothNode& sNode = n2sn->second;
+      if ( sNode._triangles.empty() )
+        continue; // not movable node
 
-    SMDS_MeshNode* node = const_cast< SMDS_MeshNode*>( n2sn->first );
-    gp_Pnt xyz = surface->Value( sNode._uv );
-    meshDS->MoveNode( node, xyz.X(), xyz.Y(), xyz.Z() );
+      SMDS_MeshNode* node = const_cast< SMDS_MeshNode*>( n2sn->first );
+      gp_Pnt xyz = surface->Value( sNode._uv );
+      meshDS->MoveNode( node, xyz.X(), xyz.Y(), xyz.Z() );
 
-    // store the new UV
-    node->SetPosition( SMDS_PositionPtr( new SMDS_FacePosition( sNode._uv.X(), sNode._uv.Y() )));
+      // store the new UV
+      node->SetPosition( SMDS_PositionPtr( new SMDS_FacePosition( sNode._uv.X(), sNode._uv.Y() )));
+    }
   }
 
   // Move medium nodes in quadratic mesh
@@ -4086,6 +4089,7 @@ void StdMeshers_Quadrangle_2D::smooth (FaceQuadStruct::Ptr quad)
       meshDS->MoveNode( node, xyz.X(), xyz.Y(), xyz.Z() );
     }
   }
+  return;
 }
 
 //================================================================================
@@ -4181,12 +4185,18 @@ bool StdMeshers_Quadrangle_2D::check()
     if ( myHelper->HasSeam() )
       for ( int i = 0; i < nbN && !nInFace; ++i )
         if ( !myHelper->IsSeamShape( nn[i]->getshapeId() ))
+        {
           nInFace = nn[i];
+          gp_XY uv = myHelper->GetNodeUV( geomFace, nInFace );
+          if ( myHelper->IsOnSeam( uv ))
+            nInFace = NULL;
+        }
 
     toCheckUV = true;
     for ( int i = 0; i < nbN; ++i )
       uv[ i ] = myHelper->GetNodeUV( geomFace, nn[i], nInFace, &toCheckUV );
 
+    bool isBad = false;
     switch ( nbN ) {
     case 4:
     {
@@ -4199,19 +4209,34 @@ bool StdMeshers_Quadrangle_2D::check()
         if ( sign1 * sign2 < 0 )
           continue; // this should not happen
       }
-      if ( sign1 * okSign < 0 )
-        badFaces.push_back ( f );
+      isBad = ( sign1 * okSign < 0 );
       break;
     }
     case 3:
     {
       double sign = getArea( uv[0], uv[1], uv[2] );
-      if ( sign * okSign < 0 )
-        badFaces.push_back ( f );
+      isBad = ( sign * okSign < 0 );
       break;
     }
     default:;
     }
+
+    // if ( isBad && myHelper->HasRealSeam() )
+    // {
+    //   // detect a case where a face intersects the seam
+    //   for ( int iPar = 1; iPar < 3; ++iPar )
+    //     if ( iPar & myHelper->GetPeriodicIndex() )
+    //     {
+    //       double min = uv[0].Coord( iPar ), max = uv[0].Coord( iPar );
+    //       for ( int i = 1; i < nbN; ++i )
+    //       {
+    //         min = Min( min, uv[i].Coord( iPar ));
+    //         max = Max( max, uv[i].Coord( iPar ));
+    //       }
+    //     }
+    // }
+    if ( isBad )
+      badFaces.push_back ( f );
   }
 
   if ( !badFaces.empty() )
@@ -4265,7 +4290,7 @@ int StdMeshers_Quadrangle_2D::getCorners(const TopoDS_Face&          theFace,
   if ( SMESH_Algo::isDegenerated( prevE ))
   {
     list<TopoDS_Edge>::reverse_iterator edge = ++theWire.rbegin();
-    while ( SMESH_Algo::isDegenerated( *edge ))
+    while ( SMESH_Algo::isDegenerated( *edge ) /*|| helper.IsRealSeam( *edge )*/)
       ++edge;
     if ( edge == theWire.rend() )
       return false;
@@ -4274,7 +4299,7 @@ int StdMeshers_Quadrangle_2D::getCorners(const TopoDS_Face&          theFace,
   list<TopoDS_Edge>::iterator edge = theWire.begin();
   for ( int iE = 0; edge != theWire.end(); ++edge, ++iE )
   {
-    if ( SMESH_Algo::isDegenerated( *edge ))
+    if ( SMESH_Algo::isDegenerated( *edge ) /*|| helper.IsRealSeam( *edge )*/)
     {
       ++theNbDegenEdges;
       continue;
index a1938bde983a2d5353f6ddc8f719caa1b2dfb2f9..b35a1425f6097be692912627de0e30f6a95c1da0 100644 (file)
@@ -158,6 +158,10 @@ class STDMESHERS_EXPORT StdMeshers_Quadrangle_2D: public SMESH_2D_Algo
                                    const bool          considerMesh = false,
                                    SMESH_MesherHelper* aFaceHelper = 0);
 
+  virtual bool IsApplicableToShape(const TopoDS_Shape & shape, bool toCheckAll) const
+  {
+    return IsApplicable( shape, toCheckAll );
+  }
   static bool IsApplicable(const TopoDS_Shape & aShape, bool toCheckAll);
 
  protected:
index bbf339a8b124c022eda732e432df85d6ad46d563..23962cba2070d95def31e5867f2d8096784b3f25 100644 (file)
@@ -29,8 +29,6 @@
 
 #include "StdMeshers_RadialPrism_3D.hxx"
 
-#include <Basics_OCCTVersion.hxx>
-
 #include "StdMeshers_ProjectionUtils.hxx"
 #include "StdMeshers_NumberOfLayers.hxx"
 #include "StdMeshers_LayerDistribution.hxx"
index 1f20b17fc9329a1e6b5d02c9a3acd34186aca824..144905e8184b5bd7d063fe793190bf94cac1d124 100644 (file)
@@ -55,6 +55,10 @@ public:
   virtual bool Evaluate(SMESH_Mesh & aMesh, const TopoDS_Shape & aShape,
                         MapShapeNbElems& aResMap);
 
+  virtual bool IsApplicableToShape(const TopoDS_Shape & shape, bool toCheckAll) const
+  {
+    return IsApplicable( shape, toCheckAll );
+  }
   static bool IsApplicable(const TopoDS_Shape & aShape, bool toCheckAll);
 
 protected:
index dc573828efbe53b0b3df87d1827214f6deae49d5..ca07b07a93b30c8922f80bec451d115b15dc305c 100644 (file)
@@ -669,7 +669,7 @@ public:
     return true;
   }
   // -----------------------------------------------------------------------------
-  //! Make mesh on an adge using assigned 1d hyp or defaut nb of segments
+  //! Make mesh on an adge using assigned 1d hyp or default nb of segments
   bool ComputeCircularEdge( SMESH_Mesh&                   aMesh,
                             const StdMeshers_FaceSidePtr& aSide )
   {
@@ -697,7 +697,7 @@ public:
     return ok;
   }
   // -----------------------------------------------------------------------------
-  //! Make mesh on an adge using assigned 1d hyp or defaut nb of segments
+  //! Make mesh on an adge using assigned 1d hyp or default nb of segments
   bool EvaluateCircularEdge(SMESH_Mesh&                  aMesh,
                             const StdMeshers_FaceSidePtr aSide,
                             MapShapeNbElems&             aResMap)
index 7270cba40d28c67a3d7340c6c30c7a7709052eaa..a029757dde07c258bee719974256ac1b78768377 100644 (file)
@@ -58,9 +58,13 @@ public:
    */
   virtual void SubmeshRestored(SMESH_subMesh* subMesh);
   
+  virtual bool IsApplicableToShape(const TopoDS_Shape & shape, bool toCheckAll) const
+  {
+    return IsApplicable( shape, toCheckAll );
+  }
   static bool IsApplicable(const TopoDS_Shape & aShape, bool toCheckAll);
 
-protected:
+ protected:
 
   int computeLayerPositions(StdMeshers_FaceSidePtr linSide,
                             std::vector< double >& positions,
index 6746a502c1daef9cd0bd9655ceae17c87baafcde..32270cdcc92af858c2ebf614bc383240250faf05 100644 (file)
@@ -1139,7 +1139,7 @@ bool StdMeshers_Regular_1D::Compute(SMESH_Mesh & theMesh, const TopoDS_Shape & t
   if ( !nFirst || !nLast )
     return error( COMPERR_BAD_INPUT_MESH, "No node on vertex");
 
-  // remove elements created by e.g. patern mapping (PAL21999)
+  // remove elements created by e.g. pattern mapping (PAL21999)
   // CLEAN event is incorrectly ptopagated seemingly due to Propagation hyp
   // so TEMPORARY solution is to clean the submesh manually
   if (SMESHDS_SubMesh * subMeshDS = meshDS->MeshElements(theShape))
index a6530b9244a5782abe3a820e82075e2aab951077..0864aaa252064714fbc3f6dab440d09870db9ca1 100644 (file)
@@ -95,7 +95,7 @@
 #include <string>
 
 #ifdef _DEBUG_
-//#define __myDEBUG
+#define __myDEBUG
 //#define __NOT_INVALIDATE_BAD_SMOOTH
 //#define __NODES_AT_POS
 #endif
@@ -114,7 +114,7 @@ namespace VISCOUS_3D
   enum UIndex { U_TGT = 1, U_SRC, LEN_TGT };
 
   const double theMinSmoothCosin = 0.1;
-  const double theSmoothThickToElemSizeRatio = 0.3;
+  const double theSmoothThickToElemSizeRatio = 0.6;
   const double theMinSmoothTriaAngle = 30;
   const double theMinSmoothQuadAngle = 45;
 
@@ -427,20 +427,21 @@ namespace VISCOUS_3D
 
     enum EFlags { TO_SMOOTH       = 0x0000001,
                   MOVED           = 0x0000002, // set by _neibors[i]->SetNewLength()
-                  SMOOTHED        = 0x0000004, // set by this->Smooth()
+                  SMOOTHED        = 0x0000004, // set by _LayerEdge::Smooth()
                   DIFFICULT       = 0x0000008, // near concave VERTEX
                   ON_CONCAVE_FACE = 0x0000010,
                   BLOCKED         = 0x0000020, // not to inflate any more
                   INTERSECTED     = 0x0000040, // close intersection with a face found
                   NORMAL_UPDATED  = 0x0000080,
-                  MARKED          = 0x0000100, // local usage
-                  MULTI_NORMAL    = 0x0000200, // a normal is invisible by some of surrounding faces
-                  NEAR_BOUNDARY   = 0x0000400, // is near FACE boundary forcing smooth
-                  SMOOTHED_C1     = 0x0000800, // is on _eosC1
-                  DISTORTED       = 0x0001000, // was bad before smoothing
-                  RISKY_SWOL      = 0x0002000, // SWOL is parallel to a source FACE
-                  SHRUNK          = 0x0004000, // target node reached a tgt position while shrink()
-                  UNUSED_FLAG     = 0x0100000  // to add use flags after
+                  UPD_NORMAL_CONV = 0x0000100, // to update normal on boundary of concave FACE
+                  MARKED          = 0x0000200, // local usage
+                  MULTI_NORMAL    = 0x0000400, // a normal is invisible by some of surrounding faces
+                  NEAR_BOUNDARY   = 0x0000800, // is near FACE boundary forcing smooth
+                  SMOOTHED_C1     = 0x0001000, // is on _eosC1
+                  DISTORTED       = 0x0002000, // was bad before smoothing
+                  RISKY_SWOL      = 0x0004000, // SWOL is parallel to a source FACE
+                  SHRUNK          = 0x0008000, // target node reached a tgt position while shrink()
+                  UNUSED_FLAG     = 0x0100000  // to add user flags after
     };
     bool Is   ( int flag ) const { return _flags & flag; }
     void Set  ( int flag ) { _flags |= flag; }
@@ -497,11 +498,14 @@ namespace VISCOUS_3D
     const gp_XYZ& PrevPos() const { return _pos[ _pos.size() - 2 ]; }
     gp_XYZ PrevCheckPos( _EdgesOnShape* eos=0 ) const;
     gp_Ax1 LastSegment(double& segLen, _EdgesOnShape& eos) const;
-    gp_XY  LastUV( const TopoDS_Face& F, _EdgesOnShape& eos ) const;
+    gp_XY  LastUV( const TopoDS_Face& F, _EdgesOnShape& eos, int which=-1 ) const;
     bool   IsOnEdge() const { return _2neibors; }
+    bool   IsOnFace() const { return ( _nodes[0]->GetPosition()->GetDim() == 2 ); }
+    int    BaseShapeDim() const { return _nodes[0]->GetPosition()->GetDim(); }
     gp_XYZ Copy( _LayerEdge& other, _EdgesOnShape& eos, SMESH_MesherHelper& helper );
     void   SetCosin( double cosin );
     void   SetNormal( const gp_XYZ& n ) { _normal = n; }
+    void   SetMaxLen( double l ) { _maxLen = l; }
     int    NbSteps() const { return _pos.size() - 1; } // nb inlation steps
     bool   IsNeiborOnEdge( const _LayerEdge* edge ) const;
     void   SetSmooLen( double len ) { // set _len at which smoothing is needed
@@ -664,6 +668,8 @@ namespace VISCOUS_3D
 
     _SolidData*            _data; // parent SOLID
 
+    _LayerEdge*      operator[](size_t i) const { return (_LayerEdge*) _edges[i]; }
+    size_t           size() const { return _edges.size(); }
     TopAbs_ShapeEnum ShapeType() const
     { return _shape.IsNull() ? TopAbs_SHAPE : _shape.ShapeType(); }
     TopAbs_ShapeEnum SWOLType() const
@@ -678,7 +684,7 @@ namespace VISCOUS_3D
 
   //--------------------------------------------------------------------------------
   /*!
-   * \brief Convex FACE whose radius of curvature is less than the thickness of 
+   * \brief Convex FACE whose radius of curvature is less than the thickness of
    *        layers. It is used to detect distortion of prisms based on a convex
    *        FACE and to update normals to enable further increasing the thickness
    */
@@ -692,7 +698,14 @@ namespace VISCOUS_3D
     // map a sub-shape to _SolidData::_edgesOnShape
     map< TGeomID, _EdgesOnShape* >  _subIdToEOS;
 
+    bool                            _isTooCurved;
     bool                            _normalsFixed;
+    bool                            _normalsFixedOnBorders; // used in putOnOffsetSurface()
+
+    double GetMaxCurvature( _SolidData&         data,
+                            _EdgesOnShape&      eof,
+                            BRepLProp_SLProps&  surfProp,
+                            SMESH_MesherHelper& helper);
 
     bool GetCenterOfCurvature( _LayerEdge*         ledge,
                                BRepLProp_SLProps&  surfProp,
@@ -757,8 +770,6 @@ namespace VISCOUS_3D
 
     int                              _nbShapesToSmooth;
 
-    //map< TGeomID,Handle(Geom_Curve)> _edge2curve;
-
     vector< _CollisionEdges >        _collisionEdges;
     set< TGeomID >                   _concaveFaces;
 
@@ -836,6 +847,8 @@ namespace VISCOUS_3D
 
     void Append( const gp_Pnt& center, _LayerEdge* ledge )
     {
+      if ( ledge->Is( _LayerEdge::MULTI_NORMAL ))
+        return;
       if ( _curvaCenters.size() > 0 )
         _segLength2.push_back( center.SquareDistance( _curvaCenters.back() ));
       _curvaCenters.push_back( center );
@@ -870,6 +883,7 @@ namespace VISCOUS_3D
                             const gp_XY&   uvToFix,
                             const double   refSign );
   };
+  struct PyDump;
   //--------------------------------------------------------------------------------
   /*!
    * \brief Builder of viscous layers
@@ -942,12 +956,15 @@ namespace VISCOUS_3D
     void makeOffsetSurface( _EdgesOnShape& eos, SMESH_MesherHelper& );
     void putOnOffsetSurface( _EdgesOnShape& eos, int infStep,
                              vector< _EdgesOnShape* >& eosC1,
-                             int smooStep=0, bool moveAll=false );
+                             int smooStep=0, int moveAll=false );
     void findCollisionEdges( _SolidData& data, SMESH_MesherHelper& helper );
+    void findEdgesToUpdateNormalNearConvexFace( _ConvexFace &       convFace,
+                                                _SolidData&         data,
+                                                SMESH_MesherHelper& helper );
     void limitMaxLenByCurvature( _SolidData& data, SMESH_MesherHelper& helper );
     void limitMaxLenByCurvature( _LayerEdge* e1, _LayerEdge* e2,
                                  _EdgesOnShape& eos1, _EdgesOnShape& eos2,
-                                 SMESH_MesherHelper& helper );
+                                 const bool isSmoothable );
     bool updateNormals( _SolidData& data, SMESH_MesherHelper& helper, int stepNb, double stepSize );
     bool updateNormalsOfConvexFaces( _SolidData&         data,
                                      SMESH_MesherHelper& helper,
@@ -987,6 +1004,7 @@ namespace VISCOUS_3D
     TopTools_MapOfShape        _shrinkedFaces;
 
     int                        _tmpFaceID;
+    PyDump*                    _pyDump;
   };
   //--------------------------------------------------------------------------------
   /*!
@@ -1034,6 +1052,7 @@ namespace VISCOUS_3D
     size_t             _iSeg[2];  // index of segment where extreme tgt node is projected
     _EdgesOnShape&     _eos;
     double             _curveLen; // length of the EDGE
+    std::pair<int,int> _eToSmooth[2]; // <from,to> indices of _LayerEdge's in _eos
 
     static Handle(Geom_Curve) CurveForSmooth( const TopoDS_Edge&  E,
                                               _EdgesOnShape&      eos,
@@ -1047,36 +1066,31 @@ namespace VISCOUS_3D
     bool Perform(_SolidData&                    data,
                  Handle(ShapeAnalysis_Surface)& surface,
                  const TopoDS_Face&             F,
-                 SMESH_MesherHelper&            helper )
-    {
-      if ( _leParams.empty() || ( !isAnalytic() && _offPoints.empty() ))
-        prepare( data );
+                 SMESH_MesherHelper&            helper );
 
-      if ( isAnalytic() )
-        return smoothAnalyticEdge( data, surface, F, helper );
-      else
-        return smoothComplexEdge ( data, surface, F, helper );
-    }
     void prepare(_SolidData& data );
 
+    void findEdgesToSmooth();
+
+    bool isToSmooth( int iE );
+
     bool smoothAnalyticEdge( _SolidData&                    data,
                              Handle(ShapeAnalysis_Surface)& surface,
                              const TopoDS_Face&             F,
                              SMESH_MesherHelper&            helper);
-
     bool smoothComplexEdge( _SolidData&                    data,
                             Handle(ShapeAnalysis_Surface)& surface,
                             const TopoDS_Face&             F,
                             SMESH_MesherHelper&            helper);
-
     gp_XYZ getNormalNormal( const gp_XYZ & normal,
                             const gp_XYZ&  edgeDir);
-
     _LayerEdge* getLEdgeOnV( bool is2nd )
     {
       return _eos._edges[ is2nd ? _eos._edges.size()-1 : 0 ]->_2neibors->_edges[ is2nd ];
     }
     bool isAnalytic() const { return !_anaCurve.IsNull(); }
+
+    void offPointsToPython() const; // debug
   };
   //--------------------------------------------------------------------------------
   /*!
@@ -1596,8 +1610,8 @@ namespace VISCOUS_3D
     // look for two neighbor not in-FACE nodes of face
     for ( int i = 0; i < 2; ++i )
     {
-      if ( nNext[i]->GetPosition()->GetDim() != 2 &&
-           nNext[i]->GetID() < nodeOnEdge->GetID() )
+      if (( nNext[i]->GetPosition()->GetDim() != 2 ) &&
+          ( nodeOnEdge->GetPosition()->GetDim() == 0 || nNext[i]->GetID() < nodeOnEdge->GetID() ))
       {
         // look for an in-FACE node
         for ( int iN = 0; iN < nbN; ++iN )
@@ -1663,14 +1677,15 @@ namespace VISCOUS_3D
   // HOWTO use: run python commands written in a console to see
   //  construction steps of viscous layers
 #ifdef __myDEBUG
-  ofstream* py;
-  int       theNbPyFunc;
-  struct PyDump {
+  ostream* py;
+  int      theNbPyFunc;
+  struct PyDump
+  {
     PyDump(SMESH_Mesh& m) {
       int tag = 3 + m.GetId();
       const char* fname = "/tmp/viscous.py";
       cout << "execfile('"<<fname<<"')"<<endl;
-      py = new ofstream(fname);
+      py = _pyStream = new ofstream(fname);
       *py << "import SMESH" << endl
           << "from salome.smesh import smeshBuilder" << endl
           << "smesh  = smeshBuilder.New(salome.myStudy)" << endl
@@ -1688,6 +1703,14 @@ namespace VISCOUS_3D
       delete py; py=0;
     }
     ~PyDump() { Finish(); cout << "NB FUNCTIONS: " << theNbPyFunc << endl; }
+    struct MyStream : public ostream
+    {
+      template <class T> ostream & operator<<( const T &anything ) { return *this ; }
+    };
+    void Pause() { py = &_mystream; }
+    void Resume() { py = _pyStream; }
+    MyStream _mystream;
+    ostream* _pyStream;
   };
 #define dumpFunction(f) { _dumpFunction(f, __LINE__);}
 #define dumpMove(n)     { _dumpMove(n, __LINE__);}
@@ -1710,7 +1733,7 @@ namespace VISCOUS_3D
 
 #else
 
-  struct PyDump { PyDump(SMESH_Mesh&) {} void Finish() {} };
+  struct PyDump { PyDump(SMESH_Mesh&) {} void Finish() {} void Pause() {} void Resume() {} };
 #define dumpFunction(f) f
 #define dumpMove(n)
 #define dumpMoveComm(n,txt)
@@ -1852,6 +1875,7 @@ SMESH_ComputeErrorPtr _ViscousBuilder::Compute(SMESH_Mesh&         theMesh,
     return SMESH_ComputeErrorPtr(); // everything already computed
 
   PyDump debugDump( theMesh );
+  _pyDump = &debugDump;
 
   // TODO: ignore already computed SOLIDs 
   if ( !findSolidsWithLayers())
@@ -2321,7 +2345,7 @@ bool _ViscousBuilder::findFacesWithLayers(const bool onlyWith)
       for ( TopoDS_Iterator vIt( edge ); vIt.More(); vIt.Next() )
       {
         TGeomID vID = getMeshDS()->ShapeToIndex( vIt.Value() );
-        bool noShrinkV = false;
+        bool noShrinkV = false, noShrinkIfAdjMeshed = false;
 
         if ( iSolid < _sdVec.size() )
         {
@@ -2331,7 +2355,8 @@ bool _ViscousBuilder::findFacesWithLayers(const bool onlyWith)
             i2S    = _sdVec[i     ]._shrinkShape2Shape.find( vID );
             i2SAdj = _sdVec[iSolid]._shrinkShape2Shape.find( vID );
             if ( i2SAdj == _sdVec[iSolid]._shrinkShape2Shape.end() )
-              noShrinkV = ( i2S->second.ShapeType() == TopAbs_EDGE || isStructured );
+              noShrinkV = (( isStructured ) ||
+                           ( noShrinkIfAdjMeshed = i2S->second.ShapeType() == TopAbs_EDGE ));
             else
               noShrinkV = ( ! i2S->second.IsSame( i2SAdj->second ));
           }
@@ -2343,8 +2368,31 @@ bool _ViscousBuilder::findFacesWithLayers(const bool onlyWith)
         else
         {
           // the adjacent SOLID has NO layers at all
-          noShrinkV = ( isStructured ||
-                        _sdVec[i]._shrinkShape2Shape[ vID ].ShapeType() == TopAbs_EDGE );
+          if ( isStructured )
+          {
+            noShrinkV = true;
+          }
+          else
+          {
+            noShrinkV = noShrinkIfAdjMeshed =
+              ( _sdVec[i]._shrinkShape2Shape[ vID ].ShapeType() == TopAbs_EDGE );
+          }
+        }
+
+        if ( noShrinkV && noShrinkIfAdjMeshed )
+        {
+          // noShrinkV if FACEs in the adjacent SOLID are meshed
+          PShapeIteratorPtr fIt = helper.GetAncestors( _sdVec[i]._shrinkShape2Shape[ vID ],
+                                                       *_mesh, TopAbs_FACE, &solid );
+          while ( fIt->more() )
+          {
+            const TopoDS_Shape* f = fIt->next();
+            if ( !f->IsSame( fWOL ))
+            {
+              noShrinkV = ! _mesh->GetSubMesh( *f )->IsEmpty();
+              break;
+            }
+          }
         }
         if ( noShrinkV )
           _sdVec[i]._noShrinkShapes.insert( vID );
@@ -2777,8 +2825,6 @@ void _ViscousBuilder::limitStepSizeByCurvature( _SolidData& data )
 {
   SMESH_MesherHelper helper( *_mesh );
 
-  const int nbTestPnt = 5; // on a FACE sub-shape
-
   BRepLProp_SLProps surfProp( 2, 1e-6 );
   data._convexFaces.clear();
 
@@ -2790,58 +2836,27 @@ void _ViscousBuilder::limitStepSizeByCurvature( _SolidData& data )
       continue;
 
     TopoDS_Face        F = TopoDS::Face( eof._shape );
-    SMESH_subMesh *   sm = eof._subMesh;
     const TGeomID faceID = eof._shapeID;
 
     BRepAdaptor_Surface surface( F, false );
     surfProp.SetSurface( surface );
 
-    bool isTooCurved = false;
-
     _ConvexFace cnvFace;
-    const double        oriFactor = ( F.Orientation() == TopAbs_REVERSED ? +1. : -1. );
-    SMESH_subMeshIteratorPtr smIt = sm->getDependsOnIterator(/*includeSelf=*/true);
-    while ( smIt->more() )
-    {
-      sm = smIt->next();
-      const TGeomID subID = sm->GetId();
-      // find _LayerEdge's of a sub-shape
-      _EdgesOnShape* eos;
-      if (( eos = data.GetShapeEdges( subID )))
-        cnvFace._subIdToEOS.insert( make_pair( subID, eos ));
-      else
-        continue;
-      // check concavity and curvature and limit data._stepSize
-      const double minCurvature =
-        1. / ( eos->_hyp.GetTotalThickness() * ( 1 + theThickToIntersection ));
-      size_t iStep = Max( 1, eos->_edges.size() / nbTestPnt );
-      for ( size_t i = 0; i < eos->_edges.size(); i += iStep )
-      {
-        gp_XY uv = helper.GetNodeUV( F, eos->_edges[ i ]->_nodes[0] );
-        surfProp.SetParameters( uv.X(), uv.Y() );
-        if ( !surfProp.IsCurvatureDefined() )
-          continue;
-        if ( surfProp.MaxCurvature() * oriFactor > minCurvature )
-        {
-          limitStepSize( data, 0.9 / surfProp.MaxCurvature() * oriFactor );
-          isTooCurved = true;
-        }
-        if ( surfProp.MinCurvature() * oriFactor > minCurvature )
-        {
-          limitStepSize( data, 0.9 / surfProp.MinCurvature() * oriFactor );
-          isTooCurved = true;
-        }
-      }
-    } // loop on sub-shapes of the FACE
+    cnvFace._face = F;
+    cnvFace._normalsFixed = false;
+    cnvFace._isTooCurved = false;
 
-    if ( !isTooCurved ) continue;
+    double maxCurvature = cnvFace.GetMaxCurvature( data, eof, surfProp, helper );
+    if ( maxCurvature > 0 )
+    {
+      limitStepSize( data, 0.9 / maxCurvature );
+      findEdgesToUpdateNormalNearConvexFace( cnvFace, data, helper );
+    }
+    if ( !cnvFace._isTooCurved ) continue;
 
     _ConvexFace & convFace =
       data._convexFaces.insert( make_pair( faceID, cnvFace )).first->second;
 
-    convFace._face = F;
-    convFace._normalsFixed = false;
-
     // skip a closed surface (data._convexFaces is useful anyway)
     bool isClosedF = false;
     helper.SetSubShape( F );
@@ -2854,6 +2869,7 @@ void _ViscousBuilder::limitStepSizeByCurvature( _SolidData& data )
     if ( isClosedF )
     {
       // limit _LayerEdge::_maxLen on the FACE
+      const double oriFactor    = ( F.Orientation() == TopAbs_REVERSED ? +1. : -1. );
       const double minCurvature =
         1. / ( eof._hyp.GetTotalThickness() * ( 1 + theThickToIntersection ));
       map< TGeomID, _EdgesOnShape* >::iterator id2eos = cnvFace._subIdToEOS.find( faceID );
@@ -2865,14 +2881,13 @@ void _ViscousBuilder::limitStepSizeByCurvature( _SolidData& data )
           _LayerEdge* ledge = eos._edges[ i ];
           gp_XY uv = helper.GetNodeUV( F, ledge->_nodes[0] );
           surfProp.SetParameters( uv.X(), uv.Y() );
-          if ( !surfProp.IsCurvatureDefined() )
-            continue;
-
-          if ( surfProp.MaxCurvature() * oriFactor > minCurvature )
-            ledge->_maxLen = Min( ledge->_maxLen, 1. / surfProp.MaxCurvature() * oriFactor );
-
-          if ( surfProp.MinCurvature() * oriFactor > minCurvature )
-            ledge->_maxLen = Min( ledge->_maxLen, 1. / surfProp.MinCurvature() * oriFactor );
+          if ( surfProp.IsCurvatureDefined() )
+          {
+            double curvature = Max( surfProp.MaxCurvature() * oriFactor,
+                                    surfProp.MinCurvature() * oriFactor );
+            if ( curvature > minCurvature )
+              ledge->SetMaxLen( Min( ledge->_maxLen, 1. / curvature ));
+          }
         }
       }
       continue;
@@ -2892,7 +2907,12 @@ void _ViscousBuilder::limitStepSizeByCurvature( _SolidData& data )
         for ( size_t j = 0; j < ledge->_simplices.size(); ++j )
           if ( ledge->_simplices[j]._nNext->GetPosition()->GetDim() < 2 )
           {
-            convFace._simplexTestEdges.push_back( ledge );
+            // do not select _LayerEdge's neighboring sharp EDGEs
+            bool sharpNbr = false;
+            for ( size_t iN = 0; iN < ledge->_neibors.size()  && !sharpNbr; ++iN )
+              sharpNbr = ( ledge->_neibors[iN]->_cosin > theMinSmoothCosin );
+            if ( !sharpNbr )
+              convFace._simplexTestEdges.push_back( ledge );
             break;
           }
       }
@@ -2942,22 +2962,11 @@ bool _ViscousBuilder::findShapesToSmooth( _SolidData& data )
   // define allowed thickness
   computeGeomSize( data ); // compute data._geomSize and _LayerEdge::_maxLen
 
-  data._maxThickness = 0;
-  data._minThickness = 1e100;
-  list< const StdMeshers_ViscousLayers* >::iterator hyp = data._hyps.begin();
-  for ( ; hyp != data._hyps.end(); ++hyp )
-  {
-    data._maxThickness = Max( data._maxThickness, (*hyp)->GetTotalThickness() );
-    data._minThickness = Min( data._minThickness, (*hyp)->GetTotalThickness() );
-  }
-  //const double tgtThick = /*Min( 0.5 * data._geomSize, */data._maxThickness;
 
   // Find shapes needing smoothing; such a shape has _LayerEdge._normal on it's
   // boundary inclined to the shape at a sharp angle
 
-  //list< TGeomID > shapesToSmooth;
   TopTools_MapOfShape edgesOfSmooFaces;
-
   SMESH_MesherHelper helper( *_mesh );
   bool ok = true;
 
@@ -2972,32 +2981,34 @@ bool _ViscousBuilder::findShapesToSmooth( _SolidData& data )
       continue;
 
     double tgtThick = eos._hyp.GetTotalThickness();
-    TopExp_Explorer eExp( edgesByGeom[iS]._shape, TopAbs_EDGE );
-    for ( ; eExp.More() && !eos._toSmooth; eExp.Next() )
+    SMESH_subMeshIteratorPtr subIt = eos._subMesh->getDependsOnIterator(/*includeSelf=*/false );
+    while ( subIt->more() && !eos._toSmooth )
     {
-      TGeomID iE = getMeshDS()->ShapeToIndex( eExp.Current() );
-      vector<_LayerEdge*>& eE = edgesByGeom[ iE ]._edges;
-      if ( eE.empty() ) continue;
+      TGeomID iSub = subIt->next()->GetId();
+      const vector<_LayerEdge*>& eSub = edgesByGeom[ iSub ]._edges;
+      if ( eSub.empty() ) continue;
 
       double faceSize;
-      for ( size_t i = 0; i < eE.size() && !eos._toSmooth; ++i )
-        if ( eE[i]->_cosin > theMinSmoothCosin )
+      for ( size_t i = 0; i < eSub.size() && !eos._toSmooth; ++i )
+        if ( eSub[i]->_cosin > theMinSmoothCosin )
         {
-          SMDS_ElemIteratorPtr fIt = eE[i]->_nodes[0]->GetInverseElementIterator(SMDSAbs_Face);
+          SMDS_ElemIteratorPtr fIt = eSub[i]->_nodes[0]->GetInverseElementIterator(SMDSAbs_Face);
           while ( fIt->more() && !eos._toSmooth )
           {
             const SMDS_MeshElement* face = fIt->next();
             if ( face->getshapeId() == eos._shapeID &&
-                 getDistFromEdge( face, eE[i]->_nodes[0], faceSize ))
+                 getDistFromEdge( face, eSub[i]->_nodes[0], faceSize ))
             {
-              eos._toSmooth = needSmoothing( eE[i]->_cosin, tgtThick, faceSize );
+              eos._toSmooth = needSmoothing( eSub[i]->_cosin,
+                                             tgtThick * eSub[i]->_lenFactor,
+                                             faceSize);
             }
           }
         }
     }
     if ( eos._toSmooth )
     {
-      for ( eExp.ReInit(); eExp.More(); eExp.Next() )
+      for ( TopExp_Explorer eExp( edgesByGeom[iS]._shape, TopAbs_EDGE ); eExp.More(); eExp.Next() )
         edgesOfSmooFaces.Add( eExp.Current() );
 
       data.PrepareEdgesToSmoothOnFace( &edgesByGeom[iS], /*substituteSrcNodes=*/false );
@@ -3041,16 +3052,16 @@ bool _ViscousBuilder::findShapesToSmooth( _SolidData& data )
           if ( endSeg->getshapeId() == (int) iS )
           {
             double segLen =
-              SMESH_TNodeXYZ( endSeg->GetNode(0) ).Distance( endSeg->GetNode(1 ));
-            eos._toSmooth = needSmoothing( cosinAbs, tgtThick, segLen );
+              SMESH_TNodeXYZ( endSeg->GetNode( 0 )).Distance( endSeg->GetNode( 1 ));
+            eos._toSmooth = needSmoothing( cosinAbs, tgtThick * eV[0]->_lenFactor, segLen );
           }
         }
         if ( eos._toSmooth )
         {
           eos._edgeSmoother = new _Smoother1D( curve, eos );
 
-          for ( size_t i = 0; i < eos._edges.size(); ++i )
-            eos._edges[i]->Set( _LayerEdge::TO_SMOOTH );
+          // for ( size_t i = 0; i < eos._edges.size(); ++i )
+          //   eos._edges[i]->Set( _LayerEdge::TO_SMOOTH );
         }
       }
     }
@@ -3066,7 +3077,8 @@ bool _ViscousBuilder::findShapesToSmooth( _SolidData& data )
 
     if ( !eos._hyp.ToSmooth() )
       for ( size_t i = 0; i < eos._edges.size(); ++i )
-        eos._edges[i]->SetCosin( 0 );
+        //eos._edges[i]->SetCosin( 0 ); // keep _cosin to use in limitMaxLenByCurvature()
+        eos._edges[i]->_lenFactor = 1;
   }
 
 
@@ -3130,19 +3142,21 @@ bool _ViscousBuilder::findShapesToSmooth( _SolidData& data )
         {
           _EdgesOnShape* eof = data.GetShapeEdges( *face );
           if ( !eof ) continue; // other solid
-          if ( !eos.HasC1( eoe ))
-          {
-            eos._eosC1.push_back( eoe );
-            eoe->_toSmooth = false;
-            data.PrepareEdgesToSmoothOnFace( eoe, /*substituteSrcNodes=*/false );
-          }
-          if ( eos._shapeID != eof->_shapeID && !eos.HasC1( eof )) 
+          if ( eos._shapeID == eof->_shapeID ) continue;
+          if ( !eos.HasC1( eof ))
           {
+            // check the FACEs
             eos._eosC1.push_back( eof );
             eof->_toSmooth = false;
             data.PrepareEdgesToSmoothOnFace( eof, /*substituteSrcNodes=*/false );
             smQueue.push_back( eof->_subMesh );
           }
+          if ( !eos.HasC1( eoe ))
+          {
+            eos._eosC1.push_back( eoe );
+            eoe->_toSmooth = false;
+            data.PrepareEdgesToSmoothOnFace( eoe, /*substituteSrcNodes=*/false );
+          }
         }
       }
     }
@@ -3298,6 +3312,7 @@ void _ViscousBuilder::setShapeData( _EdgesOnShape& eos,
     if ( eos.ShapeType() == TopAbs_FACE ) // get normals to elements on a FACE
     {
       SMESHDS_SubMesh* smDS = sm->GetSubMeshDS();
+      if ( !smDS ) return;
       eos._faceNormals.resize( smDS->NbElements() );
 
       SMDS_ElemIteratorPtr eIt = smDS->GetElements();
@@ -3429,11 +3444,12 @@ bool _ViscousBuilder::setEdgeData(_LayerEdge&         edge,
   }
 
   // find _normal
+  bool fromVonF = false;
   if ( useGeometry )
   {
-    bool fromVonF = ( eos.ShapeType() == TopAbs_VERTEX &&
-                      eos.SWOLType()  == TopAbs_FACE  &&
-                      totalNbFaces > 1 );
+    fromVonF = ( eos.ShapeType() == TopAbs_VERTEX &&
+                 eos.SWOLType()  == TopAbs_FACE  &&
+                 totalNbFaces > 1 );
 
     if ( onShrinkShape && !fromVonF ) // one of faces the node is on has no layers
     {
@@ -3535,14 +3551,19 @@ bool _ViscousBuilder::setEdgeData(_LayerEdge&         edge,
       break;
     }
     case TopAbs_VERTEX: {
-      //if ( eos.SWOLType() != TopAbs_FACE ) // else _cosin is set by getFaceDir()
+      if ( fromVonF )
+      {
+        getFaceDir( TopoDS::Face( eos._sWOL ), TopoDS::Vertex( eos._shape ),
+                    node, helper, normOK, &edge._cosin );
+      }
+      else if ( eos.SWOLType() != TopAbs_FACE ) // else _cosin is set by getFaceDir()
       {
         TopoDS_Vertex V  = TopoDS::Vertex( eos._shape );
         gp_Vec inFaceDir = getFaceDir( F, V, node, helper, normOK );
         double angle     = inFaceDir.Angle( edge._normal ); // [0,PI]
         edge._cosin      = Cos( angle );
         if ( totalNbFaces > 2 || helper.IsSeamShape( node->getshapeId() ))
-          for ( int iF = totalNbFaces-2; iF >=0; --iF )
+          for ( int iF = 1; iF < totalNbFaces; ++iF )
           {
             F = face2Norm[ iF ].first;
             inFaceDir = getFaceDir( F, V, node, helper, normOK=true );
@@ -3572,7 +3593,7 @@ bool _ViscousBuilder::setEdgeData(_LayerEdge&         edge,
     getMeshDS()->RemoveFreeNode( edge._nodes.back(), 0, /*fromGroups=*/false );
     edge._nodes.resize( 1 );
     edge._normal.SetCoord( 0,0,0 );
-    edge._maxLen = 0;
+    edge.SetMaxLen( 0 );
   }
 
   // Set the rest data
@@ -3709,7 +3730,7 @@ gp_XYZ _ViscousBuilder::getFaceNormal(const SMDS_MeshNode* node,
       isOK = false;
       return p.XYZ();
     }
-    Quantity_Parameter U,V;
+    Standard_Real U,V;
     projector.LowerDistanceParameters(U,V);
     uv.SetCoord( U,V );
   }
@@ -4120,6 +4141,8 @@ void _LayerEdge::SetDataByNeighbors( const SMDS_MeshNode* n1,
 {
   if ( eos.ShapeType() != TopAbs_EDGE )
     return;
+  if ( _curvature && Is( SMOOTHED_C1 ))
+    return;
 
   gp_XYZ  pos = SMESH_TNodeXYZ( _nodes[0] );
   gp_XYZ vec1 = pos - SMESH_TNodeXYZ( n1 );
@@ -4373,7 +4396,7 @@ void _ViscousBuilder::computeGeomSize( _SolidData& data )
     _EdgesOnShape& eos = data._edgesOnShape[ iS ];
     if ( eos._edges.empty() )
       continue;
-    // get neighbor faces intersection with which should not be considered since
+    // get neighbor faces, intersection with which should not be considered since
     // collisions are avoided by means of smoothing
     set< TGeomID > neighborFaces;
     if ( eos._hyp.ToSmooth() )
@@ -4393,16 +4416,88 @@ void _ViscousBuilder::computeGeomSize( _SolidData& data )
     for ( size_t i = 0; i < eos._edges.size(); ++i )
     {
       if ( eos._edges[i]->Is( _LayerEdge::BLOCKED )) continue;
-      eos._edges[i]->_maxLen = thinkness;
+      eos._edges[i]->SetMaxLen( thinkness );
       eos._edges[i]->FindIntersection( *searcher, intersecDist, data._epsilon, eos, &face );
       if ( intersecDist > 0 && face )
       {
         data._geomSize = Min( data._geomSize, intersecDist );
         if ( !neighborFaces.count( face->getshapeId() ))
-          eos._edges[i]->_maxLen = Min( thinkness, intersecDist / ( face->GetID() < 0 ? 3. : 2. ));
+          eos[i]->SetMaxLen( Min( thinkness, intersecDist / ( face->GetID() < 0 ? 3. : 2. )));
       }
     }
   }
+
+  data._maxThickness = 0;
+  data._minThickness = 1e100;
+  list< const StdMeshers_ViscousLayers* >::iterator hyp = data._hyps.begin();
+  for ( ; hyp != data._hyps.end(); ++hyp )
+  {
+    data._maxThickness = Max( data._maxThickness, (*hyp)->GetTotalThickness() );
+    data._minThickness = Min( data._minThickness, (*hyp)->GetTotalThickness() );
+  }
+
+  // Limit inflation step size by geometry size found by intersecting
+  // normals of _LayerEdge's with mesh faces
+  if ( data._stepSize > 0.3 * data._geomSize )
+    limitStepSize( data, 0.3 * data._geomSize );
+
+  if ( data._stepSize > data._minThickness )
+    limitStepSize( data, data._minThickness );
+
+
+  // -------------------------------------------------------------------------
+  // Detect _LayerEdge which can't intersect with opposite or neighbor layer,
+  // so no need in detecting intersection at each inflation step
+  // -------------------------------------------------------------------------
+
+  int nbSteps = data._maxThickness / data._stepSize;
+  if ( nbSteps < 3 || nbSteps * data._n2eMap.size() < 100000 )
+    return;
+
+  vector< const SMDS_MeshElement* > closeFaces;
+  int nbDetected = 0;
+
+  for ( size_t iS = 0; iS < data._edgesOnShape.size(); ++iS )
+  {
+    _EdgesOnShape& eos = data._edgesOnShape[ iS ];
+    if ( eos._edges.empty() || eos.ShapeType() != TopAbs_FACE )
+      continue;
+
+    for ( size_t i = 0; i < eos.size(); ++i )
+    {
+      SMESH_NodeXYZ p( eos[i]->_nodes[0] );
+      double radius = data._maxThickness + 2 * eos[i]->_maxLen;
+      closeFaces.clear();
+      searcher->GetElementsInSphere( p, radius, SMDSAbs_Face, closeFaces );
+
+      bool toIgnore = true;
+      for ( size_t iF = 0; iF < closeFaces.size()  && toIgnore; ++iF )
+        if ( !( toIgnore = ( closeFaces[ iF ]->getshapeId() == eos._shapeID ||
+                             data._ignoreFaceIds.count( closeFaces[ iF ]->getshapeId() ))))
+        {
+          // check if a _LayerEdge will inflate in a direction opposite to a direction
+          // toward a close face
+          bool allBehind = true;
+          for ( int iN = 0; iN < closeFaces[ iF ]->NbCornerNodes()  && allBehind; ++iN )
+          {
+            SMESH_NodeXYZ pi( closeFaces[ iF ]->GetNode( iN ));
+            allBehind = (( pi - p ) * eos[i]->_normal < 0.1 * data._stepSize );
+          }
+          toIgnore = allBehind;
+        }
+
+
+      if ( toIgnore ) // no need to detect intersection
+      {
+        eos[i]->Set( _LayerEdge::INTERSECTED );
+        ++nbDetected;
+      }
+    }
+  }
+
+  debugMsg( "Nb LE to intersect " << data._n2eMap.size()-nbDetected << ", ignore " << nbDetected );
+
+  return;
 }
 
 //================================================================================
@@ -4415,24 +4510,20 @@ bool _ViscousBuilder::inflate(_SolidData& data)
 {
   SMESH_MesherHelper helper( *_mesh );
 
-  // Limit inflation step size by geometry size found by itersecting
-  // normals of _LayerEdge's with mesh faces
-  if ( data._stepSize > 0.3 * data._geomSize )
-    limitStepSize( data, 0.3 * data._geomSize );
-
   const double tgtThick = data._maxThickness;
-  if ( data._stepSize > data._minThickness )
-    limitStepSize( data, data._minThickness );
 
   if ( data._stepSize < 1. )
     data._epsilon = data._stepSize * 1e-7;
 
   debugMsg( "-- geomSize = " << data._geomSize << ", stepSize = " << data._stepSize );
+  _pyDump->Pause();
 
   findCollisionEdges( data, helper );
 
   limitMaxLenByCurvature( data, helper );
 
+  _pyDump->Resume();
+
   // limit length of _LayerEdge's around MULTI_NORMAL _LayerEdge's
   for ( size_t i = 0; i < data._edgesOnShape.size(); ++i )
     if ( data._edgesOnShape[i].ShapeType() == TopAbs_VERTEX &&
@@ -4537,6 +4628,7 @@ bool _ViscousBuilder::inflate(_SolidData& data)
       break;
     }
 #endif
+
     // new step size
     limitStepSize( data, 0.25 * distToIntersection );
     if ( data._stepSizeNodes[0] )
@@ -4858,6 +4950,7 @@ bool _ViscousBuilder::smoothAndCheck(_SolidData& data,
       _LayerEdge*      edge = eos._edges[i];
       if ( edge->_nodes.size() < 2 ) continue;
       SMESH_TNodeXYZ tgtXYZ = edge->_nodes.back();
+      //SMESH_TNodeXYZ prevXYZ = edge->_nodes[0];
       gp_XYZ        prevXYZ = edge->PrevCheckPos( &eos );
       //const gp_XYZ& prevXYZ = edge->PrevPos();
       for ( size_t j = 0; j < edge->_simplices.size(); ++j )
@@ -4897,6 +4990,7 @@ bool _ViscousBuilder::smoothAndCheck(_SolidData& data,
   const SMDS_MeshElement* intFace = 0;
   const SMDS_MeshElement* closestFace = 0;
   _LayerEdge* le = 0;
+  bool is1stBlocked = true; // dbg
   for ( size_t iS = 0; iS < data._edgesOnShape.size(); ++iS )
   {
     _EdgesOnShape& eos = data._edgesOnShape[ iS ];
@@ -4959,7 +5053,7 @@ bool _ViscousBuilder::smoothAndCheck(_SolidData& data,
         // ignore intersection of a _LayerEdge based on a _ConvexFace with a face
         // lying on this _ConvexFace
         if ( _ConvexFace* convFace = data.GetConvexFace( intFace->getshapeId() ))
-          if ( convFace->_subIdToEOS.count ( eos._shapeID ))
+          if ( convFace->_isTooCurved && convFace->_subIdToEOS.count ( eos._shapeID ))
             continue;
 
         // ignore intersection of a _LayerEdge based on a FACE with an element on this FACE
@@ -4968,18 +5062,19 @@ bool _ViscousBuilder::smoothAndCheck(_SolidData& data,
           continue;
 
         // ignore intersection with intFace of an adjacent FACE
-        if ( dist > 0 )
+        if ( dist > 0.1 * eos._edges[i]->_len )
         {
           bool toIgnore = false;
-          if (  eos._edges[i]->Is( _LayerEdge::TO_SMOOTH ))
+          if (  eos._toSmooth )
           {
             const TopoDS_Shape& S = getMeshDS()->IndexToShape( intFace->getshapeId() );
             if ( !S.IsNull() && S.ShapeType() == TopAbs_FACE )
             {
-              TopExp_Explorer edge( eos._shape, TopAbs_EDGE );
-              for ( ; !toIgnore && edge.More(); edge.Next() )
-                // is adjacent - has a common EDGE
-                toIgnore = ( helper.IsSubShape( edge.Current(), S ));
+              TopExp_Explorer sub( eos._shape,
+                                   eos.ShapeType() == TopAbs_FACE ? TopAbs_EDGE : TopAbs_VERTEX );
+              for ( ; !toIgnore && sub.More(); sub.Next() )
+                // is adjacent - has a common EDGE or VERTEX
+                toIgnore = ( helper.IsSubShape( sub.Current(), S ));
 
               if ( toIgnore ) // check angle between normals
               {
@@ -5006,6 +5101,9 @@ bool _ViscousBuilder::smoothAndCheck(_SolidData& data,
         if ( toBlockInfaltion &&
              dist < ( eos._edges[i]->_len * theThickToIntersection ))
         {
+          if ( is1stBlocked ) { is1stBlocked = false; // debug
+            dumpFunction(SMESH_Comment("blockIntersected") <<data._index<<"_InfStep"<<infStep);
+          }
           eos._edges[i]->Set( _LayerEdge::INTERSECTED ); // not to intersect
           eos._edges[i]->Block( data );                  // not to inflate
 
@@ -5039,11 +5137,14 @@ bool _ViscousBuilder::smoothAndCheck(_SolidData& data,
     } // loop on eos._edges
   } // loop on data._edgesOnShape
 
+  if ( !is1stBlocked )
+    dumpFunctionEnd();
+
   if ( closestFace && le )
   {
 #ifdef __myDEBUG
     SMDS_MeshElement::iterator nIt = closestFace->begin_nodes();
-    cout << "Shortest distance: _LayerEdge nodes: tgt " << le->_nodes.back()->GetID()
+    cout << "#Shortest distance: _LayerEdge nodes: tgt " << le->_nodes.back()->GetID()
          << " src " << le->_nodes[0]->GetID()<< ", intersection with face ("
          << (*nIt++)->GetID()<<" "<< (*nIt++)->GetID()<<" "<< (*nIt++)->GetID()
          << ") distance = " << distToIntersection<< endl;
@@ -5237,7 +5338,8 @@ void _ViscousBuilder::makeOffsetSurface( _EdgesOnShape& eos, SMESH_MesherHelper&
 
   try
   {
-    BRepOffsetAPI_MakeOffsetShape offsetMaker( eos._shape, -offset, Precision::Confusion() );
+    BRepOffsetAPI_MakeOffsetShape offsetMaker;
+    offsetMaker.PerformByJoin( eos._shape, -offset, Precision::Confusion() );
     if ( !offsetMaker.IsDone() ) return;
 
     TopExp_Explorer fExp( offsetMaker.Shape(), TopAbs_FACE );
@@ -5264,7 +5366,7 @@ void _ViscousBuilder::putOnOffsetSurface( _EdgesOnShape&            eos,
                                           int                       infStep,
                                           vector< _EdgesOnShape* >& eosC1,
                                           int                       smooStep,
-                                          bool                      moveAll )
+                                          int                       moveAll )
 {
   _EdgesOnShape * eof = & eos;
   if ( eos.ShapeType() != TopAbs_FACE ) // eos is a boundary of C1 FACE, look for the FACE eos
@@ -5295,8 +5397,13 @@ void _ViscousBuilder::putOnOffsetSurface( _EdgesOnShape&            eos,
     edge->Unset( _LayerEdge::MARKED );
     if ( edge->Is( _LayerEdge::BLOCKED ) || !edge->_curvature )
       continue;
-    if ( !moveAll && !edge->Is( _LayerEdge::MOVED ))
+    if ( moveAll == _LayerEdge::UPD_NORMAL_CONV )
+    {
+      if ( !edge->Is( _LayerEdge::UPD_NORMAL_CONV ))
         continue;
+    }
+    else if ( !moveAll && !edge->Is( _LayerEdge::MOVED ))
+      continue;
 
     int nbBlockedAround = 0;
     for ( size_t iN = 0; iN < edge->_neibors.size(); ++iN )
@@ -5306,7 +5413,7 @@ void _ViscousBuilder::putOnOffsetSurface( _EdgesOnShape&            eos,
 
     gp_Pnt tgtP = SMESH_TNodeXYZ( edge->_nodes.back() );
     gp_Pnt2d uv = eof->_offsetSurf->NextValueOfUV( edge->_curvature->_uv, tgtP, preci );
-    if ( eof->_offsetSurf->Gap() > edge->_len ) continue; // NextValueOfUV() bug 
+    if ( eof->_offsetSurf->Gap() > edge->_len ) continue; // NextValueOfUV() bug
     edge->_curvature->_uv = uv;
     if ( eof->_offsetSurf->Gap() < 10 * preci ) continue; // same pos
 
@@ -5325,9 +5432,15 @@ void _ViscousBuilder::putOnOffsetSurface( _EdgesOnShape&            eos,
       edge->_pos.back() = newP;
 
       edge->Set( _LayerEdge::MARKED );
+      if ( moveAll == _LayerEdge::UPD_NORMAL_CONV )
+      {
+        edge->_normal = ( newP - prevP ).Normalized();
+      }
     }
   }
 
+
+
 #ifdef _DEBUG_
   // dumpMove() for debug
   size_t i = 0;
@@ -5336,7 +5449,7 @@ void _ViscousBuilder::putOnOffsetSurface( _EdgesOnShape&            eos,
       break;
   if ( i < eos._edges.size() )
   {
-    dumpFunction(SMESH_Comment("putOnOffsetSurface_F") << eos._shapeID
+    dumpFunction(SMESH_Comment("putOnOffsetSurface_S") << eos._shapeID
                  << "_InfStep" << infStep << "_" << smooStep );
     for ( ; i < eos._edges.size(); ++i )
     {
@@ -5346,6 +5459,26 @@ void _ViscousBuilder::putOnOffsetSurface( _EdgesOnShape&            eos,
     dumpFunctionEnd();
   }
 #endif
+
+  _ConvexFace* cnvFace;
+  if ( moveAll != _LayerEdge::UPD_NORMAL_CONV &&
+       eos.ShapeType() == TopAbs_FACE &&
+       (cnvFace = eos.GetData().GetConvexFace( eos._shapeID )) &&
+       !cnvFace->_normalsFixedOnBorders )
+  {
+    // put on the surface nodes built on FACE boundaries
+    SMESH_subMeshIteratorPtr smIt = eos._subMesh->getDependsOnIterator(/*includeSelf=*/false);
+    while ( smIt->more() )
+    {
+      SMESH_subMesh* sm = smIt->next();
+      _EdgesOnShape* subEOS = eos.GetData().GetShapeEdges( sm->GetId() );
+      if ( !subEOS->_sWOL.IsNull() ) continue;
+      if ( std::find( eosC1.begin(), eosC1.end(), subEOS ) != eosC1.end() ) continue;
+
+      putOnOffsetSurface( *subEOS, infStep, eosC1, smooStep, _LayerEdge::UPD_NORMAL_CONV );
+    }
+    cnvFace->_normalsFixedOnBorders = true;
+  }
 }
 
 //================================================================================
@@ -5443,6 +5576,109 @@ Handle(Geom_Curve) _Smoother1D::CurveForSmooth( const TopoDS_Edge&  E,
   return Handle(Geom_Curve)();
 }
 
+//================================================================================
+/*!
+ * \brief Smooth edges on EDGE
+ */
+//================================================================================
+
+bool _Smoother1D::Perform(_SolidData&                    data,
+                          Handle(ShapeAnalysis_Surface)& surface,
+                          const TopoDS_Face&             F,
+                          SMESH_MesherHelper&            helper )
+{
+  if ( _leParams.empty() || ( !isAnalytic() && _offPoints.empty() ))
+    prepare( data );
+
+  findEdgesToSmooth();
+  if ( isAnalytic() )
+    return smoothAnalyticEdge( data, surface, F, helper );
+  else
+    return smoothComplexEdge ( data, surface, F, helper );
+}
+
+//================================================================================
+/*!
+ * \brief Find edges to smooth
+ */
+//================================================================================
+
+void _Smoother1D::findEdgesToSmooth()
+{
+  _LayerEdge* leOnV[2] = { getLEdgeOnV(0), getLEdgeOnV(1) };
+  for ( int iEnd = 0; iEnd < 2; ++iEnd )
+    if ( leOnV[iEnd]->Is( _LayerEdge::NORMAL_UPDATED ))
+      _leOnV[iEnd]._cosin = Abs( _edgeDir[iEnd].Normalized() * leOnV[iEnd]->_normal );
+
+  _eToSmooth[0].first = _eToSmooth[0].second = 0;
+
+  for ( size_t i = 0; i < _eos.size(); ++i )
+  {
+    if ( !_eos[i]->Is( _LayerEdge::TO_SMOOTH ))
+    {
+      if ( needSmoothing( _leOnV[0]._cosin,
+                          _eos[i]->_len * leOnV[0]->_lenFactor, _curveLen * _leParams[i] ) ||
+           isToSmooth( i )
+           )
+        _eos[i]->Set( _LayerEdge::TO_SMOOTH );
+      else
+        break;
+    }
+    _eToSmooth[0].second = i+1;
+  }
+
+  _eToSmooth[1].first = _eToSmooth[1].second = _eos.size();
+
+  for ( int i = _eos.size() - 1; i >= _eToSmooth[0].second; --i )
+  {
+    if ( !_eos[i]->Is( _LayerEdge::TO_SMOOTH ))
+    {
+      if ( needSmoothing( _leOnV[1]._cosin,
+                          _eos[i]->_len * leOnV[1]->_lenFactor, _curveLen * ( 1.-_leParams[i] )) ||
+           isToSmooth( i ))
+        _eos[i]->Set( _LayerEdge::TO_SMOOTH );
+      else
+        break;
+    }
+    _eToSmooth[1].first = i;
+  }
+}
+
+//================================================================================
+/*!
+ * \brief Check if iE-th _LayerEdge needs smoothing
+ */
+//================================================================================
+
+bool _Smoother1D::isToSmooth( int iE )
+{
+  SMESH_NodeXYZ pi( _eos[iE]->_nodes[0] );
+  SMESH_NodeXYZ p0( _eos[iE]->_2neibors->srcNode(0) );
+  SMESH_NodeXYZ p1( _eos[iE]->_2neibors->srcNode(1) );
+  gp_XYZ       seg0 = pi - p0;
+  gp_XYZ       seg1 = p1 - pi;
+  gp_XYZ    tangent =  seg0 + seg1;
+  double tangentLen = tangent.Modulus();
+  double  segMinLen = Min( seg0.Modulus(), seg1.Modulus() );
+  if ( tangentLen < std::numeric_limits<double>::min() )
+    return false;
+  tangent /= tangentLen;
+
+  for ( size_t i = 0; i < _eos[iE]->_neibors.size(); ++i )
+  {
+    _LayerEdge* ne = _eos[iE]->_neibors[i];
+    if ( !ne->Is( _LayerEdge::TO_SMOOTH ) ||
+         ne->_nodes.size() < 2 ||
+         ne->_nodes[0]->GetPosition()->GetDim() != 2 )
+      continue;
+    gp_XYZ edgeVec = SMESH_NodeXYZ( ne->_nodes.back() ) - SMESH_NodeXYZ( ne->_nodes[0] );
+    double    proj = edgeVec * tangent;
+    if ( needSmoothing( 1., proj, segMinLen ))
+      return true;
+  }
+  return false;
+}
+
 //================================================================================
 /*!
  * \brief smooth _LayerEdge's on a staight EDGE or circular EDGE
@@ -5456,80 +5692,121 @@ bool _Smoother1D::smoothAnalyticEdge( _SolidData&                    data,
 {
   if ( !isAnalytic() ) return false;
 
-  const size_t iFrom = 0, iTo = _eos._edges.size();
+  size_t iFrom = 0, iTo = _eos._edges.size();
 
   if ( _anaCurve->IsKind( STANDARD_TYPE( Geom_Line )))
   {
     if ( F.IsNull() ) // 3D
     {
-      SMESH_TNodeXYZ p0   ( _eos._edges[iFrom]->_2neibors->tgtNode(0) );
-      SMESH_TNodeXYZ p1   ( _eos._edges[iTo-1]->_2neibors->tgtNode(1) );
       SMESH_TNodeXYZ pSrc0( _eos._edges[iFrom]->_2neibors->srcNode(0) );
       SMESH_TNodeXYZ pSrc1( _eos._edges[iTo-1]->_2neibors->srcNode(1) );
-      gp_XYZ newPos, lineDir = pSrc1 - pSrc0;
-      _LayerEdge* vLE0 = _eos._edges[iFrom]->_2neibors->_edges[0];
-      _LayerEdge* vLE1 = _eos._edges[iTo-1]->_2neibors->_edges[1];
-      bool shiftOnly = ( vLE0->Is( _LayerEdge::NORMAL_UPDATED ) ||
-                         vLE0->Is( _LayerEdge::BLOCKED ) ||
-                         vLE1->Is( _LayerEdge::NORMAL_UPDATED ) ||
-                         vLE1->Is( _LayerEdge::BLOCKED ));
-      for ( size_t i = iFrom; i < iTo; ++i )
-      {
-        _LayerEdge*       edge = _eos._edges[i];
-        SMDS_MeshNode* tgtNode = const_cast<SMDS_MeshNode*>( edge->_nodes.back() );
-        newPos = p0 * ( 1. - _leParams[i] ) + p1 * _leParams[i];
-
-        if ( shiftOnly || edge->Is( _LayerEdge::NORMAL_UPDATED ))
-        {
-          gp_XYZ curPos = SMESH_TNodeXYZ ( tgtNode );
-          double  shift = ( lineDir * ( newPos - pSrc0 ) -
-                            lineDir * ( curPos - pSrc0 ));
-          newPos = curPos + lineDir * shift / lineDir.SquareModulus();
-        }
-        if ( edge->Is( _LayerEdge::BLOCKED ))
+      //const   gp_XYZ lineDir = pSrc1 - pSrc0;
+      //_LayerEdge* vLE0 = getLEdgeOnV( 0 );
+      //_LayerEdge* vLE1 = getLEdgeOnV( 1 );
+      // bool shiftOnly = ( vLE0->Is( _LayerEdge::NORMAL_UPDATED ) ||
+      //                    vLE0->Is( _LayerEdge::BLOCKED ) ||
+      //                    vLE1->Is( _LayerEdge::NORMAL_UPDATED ) ||
+      //                    vLE1->Is( _LayerEdge::BLOCKED ));
+      for ( int iEnd = 0; iEnd < 2; ++iEnd )
+      {
+        iFrom = _eToSmooth[ iEnd ].first, iTo = _eToSmooth[ iEnd ].second;
+        if ( iFrom >= iTo ) continue;
+        SMESH_TNodeXYZ p0( _eos[iFrom]->_2neibors->tgtNode(0) );
+        SMESH_TNodeXYZ p1( _eos[iTo-1]->_2neibors->tgtNode(1) );
+        double param0 = ( iFrom == 0 ) ? 0. : _leParams[ iFrom-1 ];
+        double param1 = _leParams[ iTo ];
+        for ( size_t i = iFrom; i < iTo; ++i )
         {
-          SMESH_TNodeXYZ pSrc( edge->_nodes[0] );
-          double curThick = pSrc.SquareDistance( tgtNode );
-          double newThink = ( pSrc - newPos ).SquareModulus();
-          if ( newThink > curThick )
-            continue;
+          _LayerEdge*       edge = _eos[i];
+          SMDS_MeshNode* tgtNode = const_cast<SMDS_MeshNode*>( edge->_nodes.back() );
+          double           param = ( _leParams[i] - param0 ) / ( param1 - param0 );
+          gp_XYZ          newPos = p0 * ( 1. - param ) + p1 * param;
+
+          // if ( shiftOnly || edge->Is( _LayerEdge::NORMAL_UPDATED ))
+          // {
+          //   gp_XYZ curPos = SMESH_TNodeXYZ ( tgtNode );
+          //   double  shift = ( lineDir * ( newPos - pSrc0 ) -
+          //                     lineDir * ( curPos - pSrc0 ));
+          //   newPos = curPos + lineDir * shift / lineDir.SquareModulus();
+          // }
+          if ( edge->Is( _LayerEdge::BLOCKED ))
+          {
+            SMESH_TNodeXYZ pSrc( edge->_nodes[0] );
+            double curThick = pSrc.SquareDistance( tgtNode );
+            double newThink = ( pSrc - newPos ).SquareModulus();
+            if ( newThink > curThick )
+              continue;
+          }
+          edge->_pos.back() = newPos;
+          tgtNode->setXYZ( newPos.X(), newPos.Y(), newPos.Z() );
+          dumpMove( tgtNode );
         }
-        edge->_pos.back() = newPos;
-        tgtNode->setXYZ( newPos.X(), newPos.Y(), newPos.Z() );
-        dumpMove( tgtNode );
       }
     }
     else // 2D
     {
-      _LayerEdge* e0 = getLEdgeOnV( 0 );
-      _LayerEdge* e1 = getLEdgeOnV( 1 );
-      gp_XY uv0 = e0->LastUV( F, *data.GetShapeEdges( e0 ));
-      gp_XY uv1 = e1->LastUV( F, *data.GetShapeEdges( e1 ));
-      if ( e0->_nodes.back() == e1->_nodes.back() ) // closed edge
+      _LayerEdge* eV0 = getLEdgeOnV( 0 );
+      _LayerEdge* eV1 = getLEdgeOnV( 1 );
+      gp_XY      uvV0 = eV0->LastUV( F, *data.GetShapeEdges( eV0 ));
+      gp_XY      uvV1 = eV1->LastUV( F, *data.GetShapeEdges( eV1 ));
+      if ( eV0->_nodes.back() == eV1->_nodes.back() ) // closed edge
       {
         int iPeriodic = helper.GetPeriodicIndex();
         if ( iPeriodic == 1 || iPeriodic == 2 )
         {
-          uv1.SetCoord( iPeriodic, helper.GetOtherParam( uv1.Coord( iPeriodic )));
-          if ( uv0.Coord( iPeriodic ) > uv1.Coord( iPeriodic ))
-            std::swap( uv0, uv1 );
+          uvV1.SetCoord( iPeriodic, helper.GetOtherParam( uvV1.Coord( iPeriodic )));
+          if ( uvV0.Coord( iPeriodic ) > uvV1.Coord( iPeriodic ))
+            std::swap( uvV0, uvV1 );
         }
       }
-      const gp_XY rangeUV = uv1 - uv0;
-      for ( size_t i = iFrom; i < iTo; ++i )
-      {
-        if ( _eos._edges[i]->Is( _LayerEdge::BLOCKED )) continue;
-        gp_XY newUV = uv0 + _leParams[i] * rangeUV;
-        _eos._edges[i]->_pos.back().SetCoord( newUV.X(), newUV.Y(), 0 );
+      for ( int iEnd = 0; iEnd < 2; ++iEnd )
+      {
+        iFrom = _eToSmooth[ iEnd ].first, iTo = _eToSmooth[ iEnd ].second;
+        if ( iFrom >= iTo ) continue;
+        _LayerEdge* e0 = _eos[iFrom]->_2neibors->_edges[0];
+        _LayerEdge* e1 = _eos[iTo-1]->_2neibors->_edges[1];
+        gp_XY      uv0 = ( e0 == eV0 ) ? uvV0 : e0->LastUV( F, _eos );
+        gp_XY      uv1 = ( e1 == eV1 ) ? uvV1 : e1->LastUV( F, _eos );
+        double  param0 = ( iFrom == 0 ) ? 0. : _leParams[ iFrom-1 ];
+        double  param1 = _leParams[ iTo ];
+        gp_XY  rangeUV = uv1 - uv0;
+        for ( size_t i = iFrom; i < iTo; ++i )
+        {
+          if ( _eos[i]->Is( _LayerEdge::BLOCKED )) continue;
+          double param = ( _leParams[i] - param0 ) / ( param1 - param0 );
+          gp_XY newUV = uv0 + param * rangeUV;
 
-        gp_Pnt newPos = surface->Value( newUV.X(), newUV.Y() );
-        SMDS_MeshNode* tgtNode = const_cast<SMDS_MeshNode*>( _eos._edges[i]->_nodes.back() );
-        tgtNode->setXYZ( newPos.X(), newPos.Y(), newPos.Z() );
-        dumpMove( tgtNode );
+          gp_Pnt newPos = surface->Value( newUV.X(), newUV.Y() );
+          SMDS_MeshNode* tgtNode = const_cast<SMDS_MeshNode*>( _eos[i]->_nodes.back() );
+          tgtNode->setXYZ( newPos.X(), newPos.Y(), newPos.Z() );
+          dumpMove( tgtNode );
 
-        SMDS_FacePosition* pos = static_cast<SMDS_FacePosition*>( tgtNode->GetPosition() );
-        pos->SetUParameter( newUV.X() );
-        pos->SetVParameter( newUV.Y() );
+          SMDS_FacePosition* pos = static_cast<SMDS_FacePosition*>( tgtNode->GetPosition() );
+          pos->SetUParameter( newUV.X() );
+          pos->SetVParameter( newUV.Y() );
+
+          gp_XYZ newUV0( newUV.X(), newUV.Y(), 0 );
+
+          if ( !_eos[i]->Is( _LayerEdge::SMOOTHED ))
+          {
+            _eos[i]->Set( _LayerEdge::SMOOTHED ); // to check in refine() (IPAL54237)
+            if ( _eos[i]->_pos.size() > 2 )
+            {
+              // modify previous positions to make _LayerEdge less sharply bent
+              vector<gp_XYZ>& uvVec = _eos[i]->_pos;
+              const gp_XYZ  uvShift = newUV0 - uvVec.back();
+              const double     len2 = ( uvVec.back() - uvVec[ 0 ] ).SquareModulus();
+              int iPrev = uvVec.size() - 2;
+              while ( iPrev > 0 )
+              {
+                double r = ( uvVec[ iPrev ] - uvVec[0] ).SquareModulus() / len2;
+                uvVec[ iPrev ] += uvShift * r;
+                --iPrev;
+              }
+            }
+          }
+          _eos[i]->_pos.back() = newUV0;
+        }
       }
     }
     return true;
@@ -5568,9 +5845,10 @@ bool _Smoother1D::smoothAnalyticEdge( _SolidData&                    data,
       if ( uLast < 0 )
         uLast += 2 * M_PI;
       
-      for ( size_t i = iFrom; i < iTo; ++i )
+      for ( size_t i = 0; i < _eos.size(); ++i )
       {
-        if ( _eos._edges[i]->Is( _LayerEdge::BLOCKED )) continue;
+        if ( _eos[i]->Is( _LayerEdge::BLOCKED )) continue;
+        //if ( !_eos[i]->Is( _LayerEdge::TO_SMOOTH )) continue;
         double u = uLast * _leParams[i];
         gp_Pnt p = ElCLib::Value( u, newCirc );
         _eos._edges[i]->_pos.back() = p.XYZ();
@@ -5602,9 +5880,10 @@ bool _Smoother1D::smoothAnalyticEdge( _SolidData&                    data,
 
       gp_Ax2d   axis( center, vec0 );
       gp_Circ2d circ( axis, radius );
-      for ( size_t i = iFrom; i < iTo; ++i )
+      for ( size_t i = 0; i < _eos.size(); ++i )
       {
-        if ( _eos._edges[i]->Is( _LayerEdge::BLOCKED )) continue;
+        if ( _eos[i]->Is( _LayerEdge::BLOCKED )) continue;
+        //if ( !_eos[i]->Is( _LayerEdge::TO_SMOOTH )) continue;
         double    newU = uLast * _leParams[i];
         gp_Pnt2d newUV = ElCLib::Value( newU, circ );
         _eos._edges[i]->_pos.back().SetCoord( newUV.X(), newUV.Y(), 0 );
@@ -5617,6 +5896,8 @@ bool _Smoother1D::smoothAnalyticEdge( _SolidData&                    data,
         SMDS_FacePosition* pos = static_cast<SMDS_FacePosition*>( tgtNode->GetPosition() );
         pos->SetUParameter( newUV.X() );
         pos->SetVParameter( newUV.Y() );
+
+        _eos[i]->Set( _LayerEdge::SMOOTHED ); // to check in refine() (IPAL54237)
       }
     }
     return true;
@@ -5639,7 +5920,9 @@ bool _Smoother1D::smoothComplexEdge( _SolidData&                    data,
   if ( _offPoints.empty() )
     return false;
 
+  // ----------------------------------------------
   // move _offPoints along normals of _LayerEdge's
+  // ----------------------------------------------
 
   _LayerEdge* e[2] = { getLEdgeOnV(0), getLEdgeOnV(1) };
   if ( e[0]->Is( _LayerEdge::NORMAL_UPDATED ))
@@ -5683,18 +5966,23 @@ bool _Smoother1D::smoothComplexEdge( _SolidData&                    data,
     }
   }
 
+  // -----------------------------------------------------------------
   // project tgt nodes of extreme _LayerEdge's to the offset segments
+  // -----------------------------------------------------------------
 
-  if ( e[0]->Is( _LayerEdge::NORMAL_UPDATED )) _iSeg[0] = 0;
-  if ( e[1]->Is( _LayerEdge::NORMAL_UPDATED )) _iSeg[1] = _offPoints.size()-2;
+  const int updatedOrBlocked = _LayerEdge::NORMAL_UPDATED | _LayerEdge::BLOCKED;
+  if ( e[0]->Is( updatedOrBlocked )) _iSeg[0] = 0;
+  if ( e[1]->Is( updatedOrBlocked )) _iSeg[1] = _offPoints.size()-2;
 
   gp_Pnt pExtreme[2], pProj[2];
+  bool isProjected[2];
   for ( int is2nd = 0; is2nd < 2; ++is2nd )
   {
     pExtreme[ is2nd ] = SMESH_TNodeXYZ( e[is2nd]->_nodes.back() );
     int  i = _iSeg[ is2nd ];
     int di = is2nd ? -1 : +1;
-    bool projected = false;
+    bool & projected = isProjected[ is2nd ];
+    projected = false;
     double uOnSeg, distMin = Precision::Infinite(), dist, distPrev = 0;
     int nbWorse = 0;
     do {
@@ -5741,42 +6029,52 @@ bool _Smoother1D::smoothComplexEdge( _SolidData&                    data,
   gp_Vec vDiv0( pExtreme[0], pProj[0] );
   gp_Vec vDiv1( pExtreme[1], pProj[1] );
   double d0 = vDiv0.Magnitude();
-  double d1 = vDiv1.Magnitude();
-  if ( e[0]->_normal * vDiv0.XYZ() < 0 ) e[0]->_len += d0;
-  else                                   e[0]->_len -= d0;
-  if ( e[1]->_normal * vDiv1.XYZ() < 0 ) e[1]->_len += d1;
-  else                                   e[1]->_len -= d1;
+  double d1 = isProjected[1] ? vDiv1.Magnitude() : 0;
+  if ( e[0]->Is( _LayerEdge::BLOCKED )) {
+    if ( e[0]->_normal * vDiv0.XYZ() < 0 ) e[0]->_len += d0;
+    else                                   e[0]->_len -= d0;
+  }
+  if ( e[1]->Is( _LayerEdge::BLOCKED )) {
+    if ( e[1]->_normal * vDiv1.XYZ() < 0 ) e[1]->_len += d1;
+    else                                   e[1]->_len -= d1;
+  }
 
+  // ---------------------------------------------------------------------------------
   // compute normalized length of the offset segments located between the projections
+  // ---------------------------------------------------------------------------------
+
+  // temporary replace extreme _offPoints by pExtreme
+  gp_XYZ opXYZ[2] = { _offPoints[ _iSeg[0]   ]._xyz,
+                      _offPoints[ _iSeg[1]+1 ]._xyz };
+  _offPoints[ _iSeg[0]   ]._xyz = pExtreme[0].XYZ();
+  _offPoints[ _iSeg[1]+ 1]._xyz = pExtreme[1].XYZ();
 
   size_t iSeg = 0, nbSeg = _iSeg[1] - _iSeg[0] + 1;
   vector< double > len( nbSeg + 1 );
   len[ iSeg++ ] = 0;
-  len[ iSeg++ ] = pProj[ 0 ].Distance( _offPoints[ _iSeg[0]+1 ]._xyz )/* * e[0]->_lenFactor*/;
+  len[ iSeg++ ] = pProj[ 0 ].Distance( _offPoints[ _iSeg[0]+1 ]._xyz );
   for ( size_t i = _iSeg[0]+1; i <= _iSeg[1]; ++i, ++iSeg )
   {
     len[ iSeg ] = len[ iSeg-1 ] + _offPoints[i].Distance( _offPoints[i+1] );
   }
-  len[ nbSeg ] -= pProj[ 1 ].Distance( _offPoints[ _iSeg[1]+1 ]._xyz )/* * e[1]->_lenFactor*/;
+  // if ( isProjected[ 1 ])
+  //   len[ nbSeg ] -= pProj[ 1 ].Distance( _offPoints[ _iSeg[1]+1 ]._xyz );
+  // else
+  //   len[ nbSeg ] += pExtreme[ 1 ].Distance( _offPoints[ _iSeg[1]+1 ]._xyz );
 
-  // d0 *= e[0]->_lenFactor;
-  // d1 *= e[1]->_lenFactor;
   double fullLen = len.back() - d0 - d1;
   for ( iSeg = 0; iSeg < len.size(); ++iSeg )
     len[iSeg] = ( len[iSeg] - d0 ) / fullLen;
 
-  // temporary replace extreme _offPoints by pExtreme
-  gp_XYZ op[2] = { _offPoints[ _iSeg[0]   ]._xyz,
-                   _offPoints[ _iSeg[1]+1 ]._xyz };
-  _offPoints[ _iSeg[0]   ]._xyz = pExtreme[0].XYZ();
-  _offPoints[ _iSeg[1]+ 1]._xyz = pExtreme[1].XYZ();
-
+  // -------------------------------------------------------------
   // distribute tgt nodes of _LayerEdge's between the projections
+  // -------------------------------------------------------------
 
   iSeg = 0;
-  for ( size_t i = 0; i < _eos._edges.size(); ++i )
+  for ( size_t i = 0; i < _eos.size(); ++i )
   {
-    if ( _eos._edges[i]->Is( _LayerEdge::BLOCKED )) continue;
+    if ( _eos[i]->Is( _LayerEdge::BLOCKED )) continue;
+    //if ( !_eos[i]->Is( _LayerEdge::TO_SMOOTH )) continue;
     while ( iSeg+2 < len.size() && _leParams[i] > len[ iSeg+1 ] )
       iSeg++;
     double r = ( _leParams[i] - len[ iSeg ]) / ( len[ iSeg+1 ] - len[ iSeg ]);
@@ -5785,23 +6083,23 @@ bool _Smoother1D::smoothComplexEdge( _SolidData&                    data,
 
     if ( surface.IsNull() )
     {
-      _eos._edges[i]->_pos.back() = p;
+      _eos[i]->_pos.back() = p;
     }
     else // project a new node position to a FACE
     {
-      gp_Pnt2d uv ( _eos._edges[i]->_pos.back().X(), _eos._edges[i]->_pos.back().Y() );
+      gp_Pnt2d uv ( _eos[i]->_pos.back().X(), _eos[i]->_pos.back().Y() );
       gp_Pnt2d uv2( surface->NextValueOfUV( uv, p, fTol ));
 
       p = surface->Value( uv2 ).XYZ();
-      _eos._edges[i]->_pos.back().SetCoord( uv2.X(), uv2.Y(), 0 );
+      _eos[i]->_pos.back().SetCoord( uv2.X(), uv2.Y(), 0 );
     }
-    SMDS_MeshNode* tgtNode = const_cast<SMDS_MeshNode*>( _eos._edges[i]->_nodes.back() );
+    SMDS_MeshNode* tgtNode = const_cast<SMDS_MeshNode*>( _eos[i]->_nodes.back() );
     tgtNode->setXYZ( p.X(), p.Y(), p.Z() );
     dumpMove( tgtNode );
   }
 
-  _offPoints[ _iSeg[0]   ]._xyz = op[0];
-  _offPoints[ _iSeg[1]+1 ]._xyz = op[1];
+  _offPoints[ _iSeg[0]   ]._xyz = opXYZ[0];
+  _offPoints[ _iSeg[1]+1 ]._xyz = opXYZ[1];
 
   return true;
 }
@@ -5836,15 +6134,27 @@ void _Smoother1D::prepare(_SolidData& data)
     double fullLen = _leParams.back() + pPrev.Distance( SMESH_TNodeXYZ( getLEdgeOnV(1)->_nodes[0]));
     for ( size_t i = 0; i < _leParams.size()-1; ++i )
       _leParams[i] = _leParams[i+1] / fullLen;
+    _leParams.back() = 1.;
   }
 
+  _LayerEdge* leOnV[2] = { getLEdgeOnV(0), getLEdgeOnV(1) };
+
+  // get cosin to use in findEdgesToSmooth()
+  _edgeDir[0] = getEdgeDir( E, leOnV[0]->_nodes[0], data.GetHelper() );
+  _edgeDir[1] = getEdgeDir( E, leOnV[1]->_nodes[0], data.GetHelper() );
+  _leOnV[0]._cosin = Abs( leOnV[0]->_cosin );
+  _leOnV[1]._cosin = Abs( leOnV[1]->_cosin );
+  if ( _eos._sWOL.IsNull() ) // 3D
+    for ( int iEnd = 0; iEnd < 2; ++iEnd )
+      _leOnV[iEnd]._cosin = Abs( _edgeDir[iEnd].Normalized() * leOnV[iEnd]->_normal );
+
   if ( isAnalytic() )
     return;
 
   // divide E to have offset segments with low deflection
   BRepAdaptor_Curve c3dAdaptor( E );
-  const double curDeflect = 0.1; //0.3; // 0.01; // Curvature deflection
-  const double angDeflect = 0.1; //0.2; // 0.09; // Angular deflection
+  const double curDeflect = 0.1; //0.01; // Curvature deflection == |p1p2]*sin(p1p2,p1pM)
+  const double angDeflect = 0.1; //0.09; // Angular deflection == sin(p1pM,pMp2)
   GCPnts_TangentialDeflection discret(c3dAdaptor, angDeflect, curDeflect);
   if ( discret.NbPoints() <= 2 )
   {
@@ -5854,17 +6164,40 @@ void _Smoother1D::prepare(_SolidData& data)
 
   const double u0 = c3dAdaptor.FirstParameter();
   gp_Pnt p; gp_Vec tangent;
-  _offPoints.resize( discret.NbPoints() );
-  for ( size_t i = 0; i < _offPoints.size(); i++ )
+  if ( discret.NbPoints() >= (int) _eos.size() + 2 )
   {
-    double u = discret.Parameter( i+1 );
-    c3dAdaptor.D1( u, p, tangent );
-    _offPoints[i]._xyz     = p.XYZ();
-    _offPoints[i]._edgeDir = tangent.XYZ();
-    _offPoints[i]._param = GCPnts_AbscissaPoint::Length( c3dAdaptor, u0, u ) / _curveLen;
+    _offPoints.resize( discret.NbPoints() );
+    for ( size_t i = 0; i < _offPoints.size(); i++ )
+    {
+      double u = discret.Parameter( i+1 );
+      c3dAdaptor.D1( u, p, tangent );
+      _offPoints[i]._xyz     = p.XYZ();
+      _offPoints[i]._edgeDir = tangent.XYZ();
+      _offPoints[i]._param = GCPnts_AbscissaPoint::Length( c3dAdaptor, u0, u ) / _curveLen;
+    }
   }
+  else
+  {
+    std::vector< double > params( _eos.size() + 2 );
 
-  _LayerEdge* leOnV[2] = { getLEdgeOnV(0), getLEdgeOnV(1) };
+    params[0]     = data.GetHelper().GetNodeU( E, leOnV[0]->_nodes[0] );
+    params.back() = data.GetHelper().GetNodeU( E, leOnV[1]->_nodes[0] );
+    for ( size_t i = 0; i < _eos.size(); i++ )
+      params[i+1] = data.GetHelper().GetNodeU( E, _eos[i]->_nodes[0] );
+
+    if ( params[1] > params[ _eos.size() ] )
+      std::reverse( params.begin() + 1, params.end() - 1 );
+
+    _offPoints.resize( _eos.size() + 2 );
+    for ( size_t i = 0; i < _offPoints.size(); i++ )
+    {
+      const double u = params[i];
+      c3dAdaptor.D1( u, p, tangent );
+      _offPoints[i]._xyz     = p.XYZ();
+      _offPoints[i]._edgeDir = tangent.XYZ();
+      _offPoints[i]._param = GCPnts_AbscissaPoint::Length( c3dAdaptor, u0, u ) / _curveLen;
+    }
+  }
 
   // set _2edges
   _offPoints    [0]._2edges.set( &_leOnV[0], &_leOnV[0], 0.5, 0.5 );
@@ -5903,11 +6236,14 @@ void _Smoother1D::prepare(_SolidData& data)
 
   int iLBO = _offPoints.size() - 2; // last but one
 
-  _edgeDir[0] = getEdgeDir( E, leOnV[0]->_nodes[0], data.GetHelper() );
-  _edgeDir[1] = getEdgeDir( E, leOnV[1]->_nodes[0], data.GetHelper() );
-
-  _leOnV[ 0 ]._normal = getNormalNormal( leOnV[0]->_normal, _edgeDir[0] );
-  _leOnV[ 1 ]._normal = getNormalNormal( leOnV[1]->_normal, _edgeDir[1] );
+  if ( leOnV[ 0 ]->Is( _LayerEdge::MULTI_NORMAL ))
+    _leOnV[ 0 ]._normal = getNormalNormal( _eos._edges[1]->_normal, _edgeDir[0] );
+  else
+    _leOnV[ 0 ]._normal = getNormalNormal( leOnV[0]->_normal,       _edgeDir[0] );
+  if ( leOnV[ 1 ]->Is( _LayerEdge::MULTI_NORMAL ))
+    _leOnV[ 1 ]._normal = getNormalNormal( _eos._edges.back()->_normal, _edgeDir[1] );
+  else
+    _leOnV[ 1 ]._normal = getNormalNormal( leOnV[1]->_normal,           _edgeDir[1] );
   _leOnV[ 0 ]._len = 0;
   _leOnV[ 1 ]._len = 0;
   _leOnV[ 0 ]._lenFactor = _offPoints[1   ]._2edges._edges[1]->_lenFactor;
@@ -5941,7 +6277,7 @@ void _Smoother1D::prepare(_SolidData& data)
 
 //================================================================================
 /*!
- * \brief set _normal of _leOnV[is2nd] to be normal to the EDGE
+ * \brief return _normal of _leOnV[is2nd] normal to the EDGE
  */
 //================================================================================
 
@@ -5952,9 +6288,36 @@ gp_XYZ _Smoother1D::getNormalNormal( const gp_XYZ & normal,
   gp_XYZ  norm = edgeDir ^ cross;
   double  size = norm.Modulus();
 
+  // if ( size == 0 ) // MULTI_NORMAL _LayerEdge
+  //   return gp_XYZ( 1e-100, 1e-100, 1e-100 );
+
   return norm / size;
 }
 
+//================================================================================
+/*!
+ * \brief Writes a script creating a mesh composed of _offPoints
+ */
+//================================================================================
+
+void _Smoother1D::offPointsToPython() const
+{
+  const char* fname = "/tmp/offPoints.py";
+  cout << "execfile('"<<fname<<"')"<<endl;
+  ofstream py(fname);
+  py << "import SMESH" << endl
+     << "from salome.smesh import smeshBuilder" << endl
+     << "smesh  = smeshBuilder.New(salome.myStudy)" << endl
+     << "mesh   = smesh.Mesh( 'offPoints' )"<<endl;
+  for ( size_t i = 0; i < _offPoints.size(); i++ )
+  {
+    py << "mesh.AddNode( "
+       << _offPoints[i]._xyz.X() << ", "
+       << _offPoints[i]._xyz.Y() << ", "
+       << _offPoints[i]._xyz.Z() << " )" << endl;
+  }
+}
+
 //================================================================================
 /*!
  * \brief Sort _LayerEdge's by a parameter on a given EDGE
@@ -6062,43 +6425,43 @@ void _SolidData::PrepareEdgesToSmoothOnFace( _EdgesOnShape* eos, bool substitute
     }
 
     // SetSmooLen() to _LayerEdge's on FACE
-    for ( size_t i = 0; i < eos->_edges.size(); ++i )
-    {
-      eos->_edges[i]->SetSmooLen( Precision::Infinite() );
-    }
-    SMESH_subMeshIteratorPtr smIt = eos->_subMesh->getDependsOnIterator(/*includeSelf=*/false);
-    while ( smIt->more() ) // loop on sub-shapes of the FACE
-    {
-      _EdgesOnShape* eoe = GetShapeEdges( smIt->next()->GetId() );
-      if ( !eoe ) continue;
-
-      vector<_LayerEdge*>& eE = eoe->_edges;
-      for ( size_t iE = 0; iE < eE.size(); ++iE ) // loop on _LayerEdge's on EDGE or VERTEX
-      {
-        if ( eE[iE]->_cosin <= theMinSmoothCosin )
-          continue;
+    // for ( size_t i = 0; i < eos->_edges.size(); ++i )
+    // {
+    //   eos->_edges[i]->SetSmooLen( Precision::Infinite() );
+    // }
+    // SMESH_subMeshIteratorPtr smIt = eos->_subMesh->getDependsOnIterator(/*includeSelf=*/false);
+    // while ( smIt->more() ) // loop on sub-shapes of the FACE
+    // {
+    //   _EdgesOnShape* eoe = GetShapeEdges( smIt->next()->GetId() );
+    //   if ( !eoe ) continue;
 
-        SMDS_ElemIteratorPtr segIt = eE[iE]->_nodes[0]->GetInverseElementIterator(SMDSAbs_Edge);
-        while ( segIt->more() )
-        {
-          const SMDS_MeshElement* seg = segIt->next();
-          if ( !eos->_subMesh->DependsOn( seg->getshapeId() ))
-            continue;
-          if ( seg->GetNode(0) != eE[iE]->_nodes[0] )
-            continue; // not to check a seg twice
-          for ( size_t iN = 0; iN < eE[iE]->_neibors.size(); ++iN )
-          {
-            _LayerEdge* eN = eE[iE]->_neibors[iN];
-            if ( eN->_nodes[0]->getshapeId() != eos->_shapeID )
-              continue;
-            double dist    = SMESH_MeshAlgos::GetDistance( seg, SMESH_TNodeXYZ( eN->_nodes[0] ));
-            double smooLen = getSmoothingThickness( eE[iE]->_cosin, dist );
-            eN->SetSmooLen( Min( smooLen, eN->GetSmooLen() ));
-            eN->Set( _LayerEdge::NEAR_BOUNDARY );
-          }
-        }
-      }
-    }
+    //   vector<_LayerEdge*>& eE = eoe->_edges;
+    //   for ( size_t iE = 0; iE < eE.size(); ++iE ) // loop on _LayerEdge's on EDGE or VERTEX
+    //   {
+    //     if ( eE[iE]->_cosin <= theMinSmoothCosin )
+    //       continue;
+
+    //     SMDS_ElemIteratorPtr segIt = eE[iE]->_nodes[0]->GetInverseElementIterator(SMDSAbs_Edge);
+    //     while ( segIt->more() )
+    //     {
+    //       const SMDS_MeshElement* seg = segIt->next();
+    //       if ( !eos->_subMesh->DependsOn( seg->getshapeId() ))
+    //         continue;
+    //       if ( seg->GetNode(0) != eE[iE]->_nodes[0] )
+    //         continue; // not to check a seg twice
+    //       for ( size_t iN = 0; iN < eE[iE]->_neibors.size(); ++iN )
+    //       {
+    //         _LayerEdge* eN = eE[iE]->_neibors[iN];
+    //         if ( eN->_nodes[0]->getshapeId() != eos->_shapeID )
+    //           continue;
+    //         double dist    = SMESH_MeshAlgos::GetDistance( seg, SMESH_TNodeXYZ( eN->_nodes[0] ));
+    //         double smooLen = getSmoothingThickness( eE[iE]->_cosin, dist );
+    //         eN->SetSmooLen( Min( smooLen, eN->GetSmooLen() ));
+    //         eN->Set( _LayerEdge::NEAR_BOUNDARY );
+    //       }
+    //     }
+    //   }
+    // }
   } // if ( eos->ShapeType() == TopAbs_FACE )
 
   for ( size_t i = 0; i < eos->_edges.size(); ++i )
@@ -6136,6 +6499,7 @@ void _SolidData::PrepareEdgesToSmoothOnFace( _EdgesOnShape* eos, bool substitute
     avgLen      /= edge->_simplices.size();
     if (( edge->_curvature = _Curvature::New( avgNormProj, avgLen )))
     {
+      edge->Set( _LayerEdge::SMOOTHED_C1 );
       isCurved = true;
       SMDS_FacePosition* fPos = dynamic_cast<SMDS_FacePosition*>( edge->_nodes[0]->GetPosition() );
       if ( !fPos )
@@ -6231,7 +6595,7 @@ void _ViscousBuilder::limitMaxLenByCurvature( _SolidData& data, SMESH_MesherHelp
           if ( eI->_nodes[0]->GetID() < eN->_nodes[0]->GetID() ) // treat this pair once
           {
             _EdgesOnShape* eosN = data.GetShapeEdges( eN );
-            limitMaxLenByCurvature( eI, eN, eosI, *eosN, helper );
+            limitMaxLenByCurvature( eI, eN, eosI, *eosN, eosI._hyp.ToSmooth() );
           }
         }
       }
@@ -6245,7 +6609,7 @@ void _ViscousBuilder::limitMaxLenByCurvature( _SolidData& data, SMESH_MesherHelp
       for ( size_t i = 1; i < eosI._edges.size(); ++i )
       {
         _LayerEdge* eI = eosI._edges[i];
-        limitMaxLenByCurvature( eI, e0, eosI, eosI, helper );
+        limitMaxLenByCurvature( eI, e0, eosI, eosI, eosI._hyp.ToSmooth() );
         e0 = eI;
       }
     }
@@ -6258,12 +6622,17 @@ void _ViscousBuilder::limitMaxLenByCurvature( _SolidData& data, SMESH_MesherHelp
  */
 //================================================================================
 
-void _ViscousBuilder::limitMaxLenByCurvature( _LayerEdge*         e1,
-                                              _LayerEdge*         e2,
-                                              _EdgesOnShape&      eos1,
-                                              _EdgesOnShape&      eos2,
-                                              SMESH_MesherHelper& helper )
+void _ViscousBuilder::limitMaxLenByCurvature( _LayerEdge*    e1,
+                                              _LayerEdge*    e2,
+                                              _EdgesOnShape& eos1,
+                                              _EdgesOnShape& eos2,
+                                              const bool     isSmoothable )
 {
+  if (( e1->_nodes[0]->GetPosition()->GetDim() !=
+        e2->_nodes[0]->GetPosition()->GetDim() ) &&
+      ( e1->_cosin < 0.75 ))
+    return; // angle > 90 deg at e1
+
   gp_XYZ plnNorm = e1->_normal ^ e2->_normal;
   double norSize = plnNorm.SquareModulus();
   if ( norSize < std::numeric_limits<double>::min() )
@@ -6283,9 +6652,10 @@ void _ViscousBuilder::limitMaxLenByCurvature( _LayerEdge*         e1,
     double ovl = ( u1 * e1->_normal * dir12 -
                    u2 * e2->_normal * dir12 ) / dir12.SquareModulus();
     if ( ovl > theSmoothThickToElemSizeRatio )
-    {    
-      e1->_maxLen = Min( e1->_maxLen, 0.75 * u1 / e1->_lenFactor );
-      e2->_maxLen = Min( e2->_maxLen, 0.75 * u2 / e2->_lenFactor );
+    {
+      const double coef = 0.75;
+      e1->SetMaxLen( Min( e1->_maxLen, coef * u1 / e1->_lenFactor ));
+      e2->SetMaxLen( Min( e2->_maxLen, coef * u2 / e2->_lenFactor ));
     }
   }
 }
@@ -6460,7 +6830,7 @@ void _ViscousBuilder::findCollisionEdges( _SolidData& data, SMESH_MesherHelper&
         // else
         // {
         //   double shortLen = 0.75 * ( Min( dist1, dist2 ) / edge->_lenFactor );
-        //   edge->_maxLen = Min( shortLen, edge->_maxLen );
+        //   edge->SetMaxLen( Min( shortLen, edge->_maxLen ));
         // }
       }
 
@@ -6490,6 +6860,80 @@ void _ViscousBuilder::findCollisionEdges( _SolidData& data, SMESH_MesherHelper&
   }
 }
 
+//================================================================================
+/*!
+ * \brief Find _LayerEdge's located on boundary of a convex FACE whose normal
+ *        will be updated at each inflation step
+ */
+//================================================================================
+
+void _ViscousBuilder::findEdgesToUpdateNormalNearConvexFace( _ConvexFace &       convFace,
+                                                             _SolidData&         data,
+                                                             SMESH_MesherHelper& helper )
+{
+  const TGeomID convFaceID = getMeshDS()->ShapeToIndex( convFace._face );
+  const double       preci = BRep_Tool::Tolerance( convFace._face );
+  Handle(ShapeAnalysis_Surface) surface = helper.GetSurface( convFace._face );
+
+  bool edgesToUpdateFound = false;
+
+  map< TGeomID, _EdgesOnShape* >::iterator id2eos = convFace._subIdToEOS.begin();
+  for ( ; id2eos != convFace._subIdToEOS.end(); ++id2eos )
+  {
+    _EdgesOnShape& eos = * id2eos->second;
+    if ( !eos._sWOL.IsNull() ) continue;
+    if ( !eos._hyp.ToSmooth() ) continue;
+    for ( size_t i = 0; i < eos._edges.size(); ++i )
+    {
+      _LayerEdge* ledge = eos._edges[ i ];
+      if ( ledge->Is( _LayerEdge::UPD_NORMAL_CONV )) continue; // already checked
+      if ( ledge->Is( _LayerEdge::MULTI_NORMAL )) continue; // not inflatable
+
+      gp_XYZ tgtPos = ( SMESH_NodeXYZ( ledge->_nodes[0] ) +
+                        ledge->_normal * ledge->_lenFactor * ledge->_maxLen );
+
+      // the normal must be updated if distance from tgtPos to surface is less than
+      // target thickness
+
+      // find an initial UV for search of a projection of tgtPos to surface
+      const SMDS_MeshNode* nodeInFace = 0;
+      SMDS_ElemIteratorPtr fIt = ledge->_nodes[0]->GetInverseElementIterator(SMDSAbs_Face);
+      while ( fIt->more() && !nodeInFace )
+      {
+        const SMDS_MeshElement* f = fIt->next();
+        if ( convFaceID != f->getshapeId() ) continue;
+
+        SMDS_ElemIteratorPtr nIt = f->nodesIterator();
+        while ( nIt->more() && !nodeInFace )
+        {
+          const SMDS_MeshElement* n = nIt->next();
+          if ( n->getshapeId() == convFaceID )
+            nodeInFace = static_cast< const SMDS_MeshNode* >( n );
+        }
+      }
+      if ( !nodeInFace )
+        continue;
+      gp_XY uv = helper.GetNodeUV( convFace._face, nodeInFace );
+
+      // projection
+      surface->NextValueOfUV( uv, tgtPos, preci );
+      double  dist = surface->Gap();
+      if ( dist < 0.95 * ledge->_maxLen )
+      {
+        ledge->Set( _LayerEdge::UPD_NORMAL_CONV );
+        if ( !ledge->_curvature ) ledge->_curvature = new _Curvature;
+        ledge->_curvature->_uv.SetCoord( uv.X(), uv.Y() );
+        edgesToUpdateFound = true;
+      }
+    }
+  }
+
+  if ( !convFace._isTooCurved && edgesToUpdateFound )
+  {
+    data._convexFaces.insert( make_pair( convFaceID, convFace )).first->second;
+  }
+}
+
 //================================================================================
 /*!
  * \brief Modify normals of _LayerEdge's on EDGE's to avoid intersection with
@@ -6597,8 +7041,8 @@ bool _ViscousBuilder::updateNormals( _SolidData&         data,
       // compute new _normals
       for ( size_t i = 0; i < intEdgesDist.size(); ++i )
       {
-        _LayerEdge* edge2    = intEdgesDist[i].first;
-        double       distWgt = edge1->_len / intEdgesDist[i].second;
+        _LayerEdge* edge2   = intEdgesDist[i].first;
+        double      distWgt = edge1->_len / intEdgesDist[i].second;
         // if ( edge1->Is( _LayerEdge::BLOCKED ) &&
         //      edge2->Is( _LayerEdge::BLOCKED )) continue;        
         if ( edge2->Is( _LayerEdge::MARKED )) continue;
@@ -6636,12 +7080,17 @@ bool _ViscousBuilder::updateNormals( _SolidData&         data,
         e2neIt = edge2newEdge.insert( make_pair( edge1, zeroEdge )).first;
         e2neIt->second._normal += distWgt * newNormal;
         e2neIt->second._cosin   = newCos;
-        e2neIt->second._maxLen  = 0.7 * minIntDist / edge1->_lenFactor;
+        e2neIt->second.SetMaxLen( 0.7 * minIntDist / edge1->_lenFactor );
         if ( iter > 0 && sgn1 * sgn2 < 0 && edge1->_cosin < 0 )
           e2neIt->second._normal += dir2;
+
         e2neIt = edge2newEdge.insert( make_pair( edge2, zeroEdge )).first;
         e2neIt->second._normal += distWgt * newNormal;
-        e2neIt->second._cosin   = edge2->_cosin;
+        if ( Precision::IsInfinite( zeroEdge._maxLen ))
+        {
+          e2neIt->second._cosin  = edge2->_cosin;
+          e2neIt->second.SetMaxLen( 1.3 * minIntDist / edge1->_lenFactor );
+        }
         if ( iter > 0 && sgn1 * sgn2 < 0 && edge2->_cosin < 0 )
           e2neIt->second._normal += dir1;
       }
@@ -6658,9 +7107,10 @@ bool _ViscousBuilder::updateNormals( _SolidData&         data,
     for ( e2neIt = edge2newEdge.begin(); e2neIt != edge2newEdge.end(); ++e2neIt )
     {
       _LayerEdge*    edge = e2neIt->first;
-      if ( edge->Is( _LayerEdge::BLOCKED )) continue;
       _LayerEdge& newEdge = e2neIt->second;
       _EdgesOnShape*  eos = data.GetShapeEdges( edge );
+      if ( edge->Is( _LayerEdge::BLOCKED && newEdge._maxLen > edge->_len ))
+        continue;
 
       // Check if a new _normal is OK:
       newEdge._normal.Normalize();
@@ -6669,7 +7119,7 @@ bool _ViscousBuilder::updateNormals( _SolidData&         data,
         if ( newEdge._maxLen < edge->_len && iter > 0 ) // limit _maxLen
         {
           edge->InvalidateStep( stepNb + 1, *eos, /*restoreLength=*/true  );
-          edge->_maxLen = newEdge._maxLen;
+          edge->SetMaxLen( newEdge._maxLen );
           edge->SetNewLength( newEdge._maxLen, *eos, helper );
         }
         continue; // the new _normal is bad
@@ -6942,6 +7392,8 @@ bool _ViscousBuilder::updateNormalsOfConvexFaces( _SolidData&         data,
   for ( ; id2face != data._convexFaces.end(); ++id2face )
   {
     _ConvexFace & convFace = (*id2face).second;
+    convFace._normalsFixedOnBorders = false; // to update at each inflation step
+
     if ( convFace._normalsFixed )
       continue; // already fixed
     if ( convFace.CheckPrisms() )
@@ -7304,6 +7756,59 @@ bool _ViscousBuilder::updateNormalsOfConvexFaces( _SolidData&         data,
   return true;
 }
 
+//================================================================================
+/*!
+ * \brief Return max curvature of a FACE
+ */
+//================================================================================
+
+double _ConvexFace::GetMaxCurvature( _SolidData&         data,
+                                     _EdgesOnShape&      eof,
+                                     BRepLProp_SLProps&  surfProp,
+                                     SMESH_MesherHelper& helper)
+{
+  double maxCurvature = 0;
+
+  TopoDS_Face F = TopoDS::Face( eof._shape );
+
+  const int           nbTestPnt = 5;
+  const double        oriFactor = ( F.Orientation() == TopAbs_REVERSED ? +1. : -1. );
+  SMESH_subMeshIteratorPtr smIt = eof._subMesh->getDependsOnIterator(/*includeSelf=*/true);
+  while ( smIt->more() )
+  {
+    SMESH_subMesh* sm = smIt->next();
+    const TGeomID subID = sm->GetId();
+
+    // find _LayerEdge's of a sub-shape
+    _EdgesOnShape* eos;
+    if (( eos = data.GetShapeEdges( subID )))
+      this->_subIdToEOS.insert( make_pair( subID, eos ));
+    else
+      continue;
+
+    // check concavity and curvature and limit data._stepSize
+    const double minCurvature =
+      1. / ( eos->_hyp.GetTotalThickness() * ( 1 + theThickToIntersection ));
+    size_t iStep = Max( 1, eos->_edges.size() / nbTestPnt );
+    for ( size_t i = 0; i < eos->_edges.size(); i += iStep )
+    {
+      gp_XY uv = helper.GetNodeUV( F, eos->_edges[ i ]->_nodes[0] );
+      surfProp.SetParameters( uv.X(), uv.Y() );
+      if ( surfProp.IsCurvatureDefined() )
+      {
+        double curvature = Max( surfProp.MaxCurvature() * oriFactor,
+                                surfProp.MinCurvature() * oriFactor );
+        maxCurvature = Max( maxCurvature, curvature );
+
+        if ( curvature > minCurvature )
+          this->_isTooCurved = true;
+      }
+    }
+  } // loop on sub-shapes of the FACE
+
+  return maxCurvature;
+}
+
 //================================================================================
 /*!
  * \brief Finds a center of curvature of a surface at a _LayerEdge
@@ -7512,7 +8017,7 @@ bool _LayerEdge::FindIntersection( SMESH_ElementSearcher&   searcher,
 
 gp_XYZ _LayerEdge::PrevCheckPos( _EdgesOnShape* eos ) const
 {
-  size_t i = Is( NORMAL_UPDATED ) ? _pos.size()-2 : 0;
+  size_t i = Is( NORMAL_UPDATED ) && IsOnFace() ? _pos.size()-2 : 0;
 
   if ( !eos || eos->_sWOL.IsNull() )
     return _pos[ i ];
@@ -7586,13 +8091,14 @@ gp_Ax1 _LayerEdge::LastSegment(double& segLen, _EdgesOnShape& eos) const
 
 //================================================================================
 /*!
- * \brief Return the last position of the target node on a FACE. 
+ * \brief Return the last (or \a which) position of the target node on a FACE. 
  *  \param [in] F - the FACE this _LayerEdge is inflated along
+ *  \param [in] which - index of position
  *  \return gp_XY - result UV
  */
 //================================================================================
 
-gp_XY _LayerEdge::LastUV( const TopoDS_Face& F, _EdgesOnShape& eos ) const
+gp_XY _LayerEdge::LastUV( const TopoDS_Face& F, _EdgesOnShape& eos, int which ) const
 {
   if ( F.IsSame( eos._sWOL )) // F is my FACE
     return gp_XY( _pos.back().X(), _pos.back().Y() );
@@ -7601,7 +8107,7 @@ gp_XY _LayerEdge::LastUV( const TopoDS_Face& F, _EdgesOnShape& eos ) const
     return gp_XY( 1e100, 1e100 );
 
   // _sWOL is EDGE of F; _pos.back().X() is the last U on the EDGE
-  double f, l, u = _pos.back().X();
+  double f, l, u = _pos[ which < 0 ? _pos.size()-1 : which ].X();
   Handle(Geom2d_Curve) C2d = BRep_Tool::CurveOnSurface( TopoDS::Edge(eos._sWOL), F, f,l);
   if ( !C2d.IsNull() && f <= u && u <= l )
     return C2d->Value( u ).XY();
@@ -7679,7 +8185,7 @@ bool _LayerEdge::SegTriaInter( const gp_Ax1& lastSegment,
  *  \param [in] eov - EOS of the VERTEX
  *  \param [in] eos - EOS of the FACE
  *  \param [in] step - inflation step
- *  \param [in,out] badSmooEdges - not untangled _LayerEdge's
+ *  \param [in,out] badSmooEdges - tangled _LayerEdge's
  */
 //================================================================================
 
@@ -9031,7 +9537,12 @@ void _LayerEdge::Block( _SolidData& data )
   //if ( Is( BLOCKED )) return;
   Set( BLOCKED );
 
-  _maxLen = _len;
+  SMESH_Comment msg( "#BLOCK shape=");
+  msg << data.GetShapeEdges( this )->_shapeID
+      << ", nodes " << _nodes[0]->GetID() << ", " << _nodes.back()->GetID();
+  dumpCmd( msg + " -- BEGIN");
+
+  SetMaxLen( _len );
   std::queue<_LayerEdge*> queue;
   queue.push( this );
 
@@ -9055,16 +9566,19 @@ void _LayerEdge::Block( _SolidData& data )
       double newMaxLen = edge->_maxLen + 0.5 * Sqrt( minDist );
       //if ( edge->_nodes[0]->getshapeId() == neibor->_nodes[0]->getshapeId() ) viscous_layers_00/A3
       {
-        newMaxLen *= edge->_lenFactor / neibor->_lenFactor;
+        //newMaxLen *= edge->_lenFactor / neibor->_lenFactor;
+        // newMaxLen *= Min( edge->_lenFactor / neibor->_lenFactor,
+        //                   neibor->_lenFactor / edge->_lenFactor );
       }
       if ( neibor->_maxLen > newMaxLen )
       {
-        neibor->_maxLen = newMaxLen;
+        neibor->SetMaxLen( newMaxLen );
         if ( neibor->_maxLen < neibor->_len )
         {
           _EdgesOnShape* eos = data.GetShapeEdges( neibor );
+          int       lastStep = neibor->Is( BLOCKED ) ? 1 : 0;
           while ( neibor->_len > neibor->_maxLen &&
-                  neibor->NbSteps() > 1 )
+                  neibor->NbSteps() > lastStep )
             neibor->InvalidateStep( neibor->NbSteps(), *eos, /*restoreLength=*/true );
           neibor->SetNewLength( neibor->_maxLen, *eos, data.GetHelper() );
           //neibor->Block( data );
@@ -9073,6 +9587,7 @@ void _LayerEdge::Block( _SolidData& data )
       }
     }
   }
+  dumpCmd( msg + " -- END");
 }
 
 //================================================================================
@@ -9115,9 +9630,15 @@ void _LayerEdge::InvalidateStep( size_t curStep, const _EdgesOnShape& eos, bool
 
     if ( restoreLength )
     {
-      _len -= ( nXYZ.XYZ() - curXYZ ).Modulus() / _lenFactor;
+      if ( NbSteps() == 0 )
+        _len = 0.;
+      else if ( IsOnFace() && Is( MOVED ))
+        _len = ( nXYZ.XYZ() - SMESH_NodeXYZ( _nodes[0] )) * _normal;
+      else
+        _len -= ( nXYZ.XYZ() - curXYZ ).Modulus() / _lenFactor;
     }
   }
+  return;
 }
 
 //================================================================================
@@ -9153,10 +9674,23 @@ void _LayerEdge::SmoothPos( const vector< double >& segLen, const double tol )
   int iSmoothed = GetSmoothedPos( tol );
   if ( !iSmoothed ) return;
 
-  //if ( 1 || Is( DISTORTED ))
+  gp_XYZ normal = _normal;
+  if ( Is( NORMAL_UPDATED ))
   {
-    gp_XYZ normal = _normal;
-    if ( Is( NORMAL_UPDATED ))
+    double minDot = 1;
+    for ( size_t i = 0; i < _neibors.size(); ++i )
+    {
+      if ( _neibors[i]->IsOnFace() )
+      {
+        double dot = _normal * _neibors[i]->_normal;
+        if ( dot < minDot )
+        {
+          normal = _neibors[i]->_normal;
+          minDot = dot;
+        }
+      }
+    }
+    if ( minDot == 1. )
       for ( size_t i = 1; i < _pos.size(); ++i )
       {
         normal = _pos[i] - _pos[0];
@@ -9167,42 +9701,29 @@ void _LayerEdge::SmoothPos( const vector< double >& segLen, const double tol )
           break;
         }
       }
-    const double r = 0.2;
-    for ( int iter = 0; iter < 50; ++iter )
+  }
+  const double r = 0.2;
+  for ( int iter = 0; iter < 50; ++iter )
+  {
+    double minDot = 1;
+    for ( size_t i = Max( 1, iSmoothed-1-iter ); i < _pos.size()-1; ++i )
     {
-      double minDot = 1;
-      for ( size_t i = Max( 1, iSmoothed-1-iter ); i < _pos.size()-1; ++i )
-      {
-        gp_XYZ midPos = 0.5 * ( _pos[i-1] + _pos[i+1] );
-        gp_XYZ newPos = ( 1-r ) * midPos + r * _pos[i];
-        _pos[i] = newPos;
-        double midLen = 0.5 * ( segLen[i-1] + segLen[i+1] );
-        double newLen = ( 1-r ) * midLen + r * segLen[i];
-        const_cast< double& >( segLen[i] ) = newLen;
-        // check angle between normal and (_pos[i+1], _pos[i] )
-        gp_XYZ posDir = _pos[i+1] - _pos[i];
-        double size   = posDir.SquareModulus();
-        if ( size > RealSmall() )
-          minDot = Min( minDot, ( normal * posDir ) * ( normal * posDir ) / size );
-      }
-      if ( minDot > 0.5 * 0.5 )
-        break;
+      gp_XYZ midPos = 0.5 * ( _pos[i-1] + _pos[i+1] );
+      gp_XYZ newPos = ( 1-r ) * midPos + r * _pos[i];
+      _pos[i] = newPos;
+      double midLen = 0.5 * ( segLen[i-1] + segLen[i+1] );
+      double newLen = ( 1-r ) * midLen + r * segLen[i];
+      const_cast< double& >( segLen[i] ) = newLen;
+      // check angle between normal and (_pos[i+1], _pos[i] )
+      gp_XYZ posDir = _pos[i+1] - _pos[i];
+      double size   = posDir.SquareModulus();
+      if ( size > RealSmall() )
+        minDot = Min( minDot, ( normal * posDir ) * ( normal * posDir ) / size );
     }
+    if ( minDot > 0.5 * 0.5 )
+      break;
   }
-  // else
-  // {
-  //   for ( size_t i = 1; i < _pos.size()-1; ++i )
-  //   {
-  //     if ((int) i < iSmoothed  &&  ( segLen[i] / segLen.back() < 0.5 ))
-  //       continue;
-
-  //     double     wgt = segLen[i] / segLen.back();
-  //     gp_XYZ normPos = _pos[0] + _normal * wgt * _len;
-  //     gp_XYZ tgtPos  = ( 1 - wgt ) * _pos[0] +  wgt * _pos.back();
-  //     gp_XYZ newPos  = ( 1 - wgt ) * normPos +  wgt * tgtPos;
-  //     _pos[i] = newPos;
-  //   }
-  // }
+  return;
 }
 
 //================================================================================
@@ -9227,6 +9748,7 @@ std::string _LayerEdge::DumpFlags() const
       case BLOCKED:         dump << "BLOCKED";         break;
       case INTERSECTED:     dump << "INTERSECTED";     break;
       case NORMAL_UPDATED:  dump << "NORMAL_UPDATED";  break;
+      case UPD_NORMAL_CONV: dump << "UPD_NORMAL_CONV"; break;
       case MARKED:          dump << "MARKED";          break;
       case MULTI_NORMAL:    dump << "MULTI_NORMAL";    break;
       case NEAR_BOUNDARY:   dump << "NEAR_BOUNDARY";   break;
@@ -9242,11 +9764,11 @@ std::string _LayerEdge::DumpFlags() const
   return dump;
 }
 
+
 //================================================================================
 /*!
-  case brief:
-  default:
-*/
+ * \brief Create layers of prisms
+ */
 //================================================================================
 
 bool _ViscousBuilder::refine(_SolidData& data)
@@ -9262,7 +9784,7 @@ bool _ViscousBuilder::refine(_SolidData& data)
   double f,l, u = 0;
   gp_XY uv;
   vector< gp_XYZ > pos3D;
-  bool isOnEdge;
+  bool isOnEdge, isTooConvexFace = false;
   TGeomID prevBaseId = -1;
   TNode2Edge* n2eMap = 0;
   TNode2Edge::iterator n2e;
@@ -9301,11 +9823,11 @@ bool _ViscousBuilder::refine(_SolidData& data)
       surface  = helper.GetSurface( geomFace );
       // propagate _toSmooth back to _eosC1, which was unset in findShapesToSmooth()
       for ( size_t i = 0; i < eos._eosC1.size(); ++i )
-      {
         eos._eosC1[ i ]->_toSmooth = true;
-        for ( size_t j = 0; j < eos._eosC1[i]->_edges.size(); ++j )
-          eos._eosC1[i]->_edges[j]->Set( _LayerEdge::SMOOTHED_C1 );
-      }
+
+      isTooConvexFace = false;
+      if ( _ConvexFace* cf = data.GetConvexFace( eos._shapeID ))
+        isTooConvexFace = cf->_isTooCurved;
     }
 
     vector< double > segLen;
@@ -9321,8 +9843,8 @@ bool _ViscousBuilder::refine(_SolidData& data)
       if ( eos._sWOL.IsNull() )
       {
         bool useNormal = true;
-        bool   usePos  = false;
-        bool smoothed  = false;
+        bool    usePos = false;
+        bool  smoothed = false;
         double   preci = 0.1 * edge._len;
         if ( eos._toSmooth && edge._pos.size() > 2 )
         {
@@ -9330,8 +9852,7 @@ bool _ViscousBuilder::refine(_SolidData& data)
         }
         if ( smoothed )
         {
-          if ( !surface.IsNull() &&
-               !data._convexFaces.count( eos._shapeID )) // edge smoothed on FACE
+          if ( !surface.IsNull() && !isTooConvexFace ) // edge smoothed on FACE
           {
             useNormal = usePos = false;
             gp_Pnt2d uv = helper.GetNodeUV( geomFace, edge._nodes[0] );
@@ -9406,8 +9927,20 @@ bool _ViscousBuilder::refine(_SolidData& data)
       }
       else if ( eos._isRegularSWOL ) // usual SWOL
       {
-        for ( size_t j = 1; j < edge._pos.size(); ++j )
-          segLen[j] = segLen[j-1] + (edge._pos[j-1] - edge._pos[j] ).Modulus();
+        if ( edge.Is( _LayerEdge::SMOOTHED ))
+        {
+          SMESH_NodeXYZ p0( edge._nodes[0] );
+          for ( size_t j = 1; j < edge._pos.size(); ++j )
+          {
+            gp_XYZ pj = surface->Value( edge._pos[j].X(), edge._pos[j].Y() ).XYZ();
+            segLen[j] = ( pj - p0 ) * edge._normal;
+          }
+        }
+        else
+        {
+          for ( size_t j = 1; j < edge._pos.size(); ++j )
+            segLen[j] = segLen[j-1] + (edge._pos[j-1] - edge._pos[j] ).Modulus();
+        }
       }
       else if ( !surface.IsNull() ) // SWOL surface with singularities
       {
@@ -11140,11 +11673,11 @@ bool _ViscousBuilder::addBoundaryElements(_SolidData& data)
         const SMDS_MeshNode* tgtN0 = ledges[0]->_nodes.back();
         const SMDS_MeshNode* tgtN1 = ledges[1]->_nodes.back();
         int nbSharedPyram = 0;
-        SMDS_ElemIteratorPtr vIt = tgtN0->GetInverseElementIterator(SMDSAbs_Volume);
+        SMDS_ElemIteratorPtr vIt = tgtN1->GetInverseElementIterator(SMDSAbs_Volume);
         while ( vIt->more() )
         {
           const SMDS_MeshElement* v = vIt->next();
-          nbSharedPyram += int( v->GetNodeIndex( tgtN1 ) >= 0 );
+          nbSharedPyram += int( v->GetNodeIndex( tgtN0 ) >= 0 );
         }
         if ( nbSharedPyram > 1 )
           continue; // not free border of the pyramid
index ecd62abc20462cf179b9dd8fb116eb631d0b7dad..971cebf884654ad32cba271fd510264247012a62 100644 (file)
@@ -1318,7 +1318,7 @@ void _ViscousBuilder2D::setLayerEdgeData( _LayerEdge&                 lEdge,
     faceProj->Perform( p );
     if ( !faceProj->IsDone() || faceProj->NbPoints() < 1 )
       return setLayerEdgeData( lEdge, u, pcurve, curve, p, reverse, NULL );
-    Quantity_Parameter U,V;
+    Standard_Real U,V;
     faceProj->LowerDistanceParameters(U,V);
     lEdge._normal2D.SetCoord( U - uv.X(), V - uv.Y() );
     lEdge._normal2D.Normalize();
index 7eb2f33484b97daa5729fcdb4ff5b7b893dc90cc..f9ad75818d814768a43d5f10bc1aaee0134180e9 100644 (file)
 #include <Expr_NamedUnknown.hxx>
 #include <Expr_GeneralExpression.hxx>
 
-#if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
-#define NO_CAS_CATCH
-#endif
-
 #include <Standard_Failure.hxx>
-
-#ifdef NO_CAS_CATCH
 #include <Standard_ErrorHandler.hxx>
-#endif
 
 #ifdef WIN32
 # include <algorithm>
@@ -356,12 +349,9 @@ void StdMeshersGUI_DistrPreview::update()
   x = y = 0;
 
   try {   
-#ifdef NO_CAS_CATCH
     OCC_CATCH_SIGNALS;
-#endif
     replot();
   } catch(Standard_Failure) {
-    Handle(Standard_Failure) aFail = Standard_Failure::Caught();
   }
 }
 
@@ -404,13 +394,10 @@ bool StdMeshersGUI_DistrPreview::init( const QString& str )
   Kernel_Utils::Localizer loc;
   bool parsed_ok = true;
   try {
-#ifdef NO_CAS_CATCH
     OCC_CATCH_SIGNALS;
-#endif
     myExpr = ExprIntrp_GenExp::Create();
     myExpr->Process( ( Standard_CString ) str.toLatin1().data() );
   } catch(Standard_Failure) {
-    Handle(Standard_Failure) aFail = Standard_Failure::Caught();
     parsed_ok = false;
   }
 
@@ -446,12 +433,9 @@ double StdMeshersGUI_DistrPreview::calc( bool& ok )
 
   ok = true;
   try {   
-#ifdef NO_CAS_CATCH
     OCC_CATCH_SIGNALS;
-#endif
     res = myExpr->Expression()->Evaluate( myVars, myValues );
   } catch(Standard_Failure) {
-    Handle(Standard_Failure) aFail = Standard_Failure::Caught();
     ok = false;
     res = 0.0;
   }
@@ -472,16 +456,13 @@ bool StdMeshersGUI_DistrPreview::convert( double& v ) const
   case EXPONENT:
     {
       try { 
-#ifdef NO_CAS_CATCH
         OCC_CATCH_SIGNALS;
-#endif
         // in StdMeshers_NumberOfSegments.cc
         // const double PRECISION = 1e-7;
         //
         if(v < -7) v = -7.0;
         v = pow( 10.0, v );
       } catch(Standard_Failure) {
-        Handle(Standard_Failure) aFail = Standard_Failure::Caught();
         v = 0.0;
         ok = false;
       }
index 50a2d05c94f9c374e55212421bfd2265eacfa91e..71758729d216009394bb970a784936931ccaf698 100644 (file)
 #
 # See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 #
+
 IF(SALOME_BUILD_DOC)
   ADD_SUBDIRECTORY(doc)
 ENDIF(SALOME_BUILD_DOC)
 
-INCLUDE(UsePyQt)
+IF(SALOME_BUILD_GUI)
+  INCLUDE(UsePyQt)
+ENDIF(SALOME_BUILD_GUI)
 
 # --- scripts ---
 
 # scripts / static
-SET(plugin_SCRIPTS
+SET(_plugin_SCRIPTS
   MGCleanerMonPlugDialog.py
   MGCleanerMonViewText.py
   MGCleanerplug_plugin.py 
 )
 
-# --- resources ---
-
-# uic files / to be processed by pyuic
-SET(_pyuic_files
-  MGCleanerPlugDialog.ui
-  MGCleanerViewText.ui
-)
-
-# scripts / pyuic wrappings
-PYQT_WRAP_UIC(_pyuic_SCRIPTS ${_pyuic_files})
+IF(SALOME_BUILD_GUI)
+  # uic files / to be processed by pyuic
+  SET(_pyuic_FILES
+    MGCleanerPlugDialog.ui
+    MGCleanerViewText.ui
+  )
+  # scripts / pyuic wrappings
+  PYQT_WRAP_UIC(_pyuic_SCRIPTS ${_pyuic_FILES} TARGET_NAME _target_name_pyuic)
+ENDIF(SALOME_BUILD_GUI)
 
 # --- rules ---
 
-SALOME_INSTALL_SCRIPTS("${plugin_SCRIPTS}" ${SALOME_SMESH_INSTALL_PLUGINS})
+SALOME_INSTALL_SCRIPTS("${_plugin_SCRIPTS}" ${SALOME_SMESH_INSTALL_PLUGINS})
 
 IF(SALOME_BUILD_GUI)
-  SALOME_INSTALL_SCRIPTS("${_pyuic_SCRIPTS}" ${SALOME_SMESH_INSTALL_PLUGINS})
-ENDIF(SALOME_BUILD_GUI)
\ No newline at end of file
+  SALOME_INSTALL_SCRIPTS("${_pyuic_SCRIPTS}" ${SALOME_SMESH_INSTALL_PLUGINS} TARGET_NAME _target_name_pyuic_py)
+  # add dependency of compiled py files on uic files in order
+  # to avoid races problems when compiling in parallel
+  ADD_DEPENDENCIES(${_target_name_pyuic_py} ${_target_name_pyuic})
+ENDIF(SALOME_BUILD_GUI)
index 2125c0be1148379f53dceef605f0ff0e29f558d5..44c8cae1c4386b02a42072329183ae01a10726db 100644 (file)
@@ -38,7 +38,7 @@ SET(_link_LIBRARIES
 # --- scripts ---
 
 # scripts / static
-SET(plugin_SCRIPTS
+SET(_plugin_SCRIPTS
   meshcut_plugin.py
 )
 
@@ -61,26 +61,25 @@ SET(MeshCut_SOURCES
 )
 
 IF(SALOME_BUILD_GUI)
-  # --- resources ---
-
   # uic files / to be processed by pyuic
-  SET(_pyuic_files
+  SET(_pyuic_FILES
     MeshCutDialog.ui
   )
-
   # scripts / pyuic wrappings
-  PYQT_WRAP_UIC(_pyuic_SCRIPTS ${_pyuic_files})
-
+  PYQT_WRAP_UIC(_pyuic_SCRIPTS ${_pyuic_FILES} TARGET_NAME _target_name_pyuic)
 ENDIF(SALOME_BUILD_GUI)
 
 # --- rules ---
 
-SALOME_INSTALL_SCRIPTS("${plugin_SCRIPTS}" ${SALOME_SMESH_INSTALL_PLUGINS})
+SALOME_INSTALL_SCRIPTS("${_plugin_SCRIPTS}" ${SALOME_SMESH_INSTALL_PLUGINS})
 
 ADD_EXECUTABLE(MeshCut ${MeshCut_SOURCES})
 TARGET_LINK_LIBRARIES(MeshCut ${_link_LIBRARIES})
 INSTALL(TARGETS MeshCut EXPORT ${PROJECT_NAME}TargetGroup DESTINATION ${SALOME_INSTALL_BINS})
 
 IF(SALOME_BUILD_GUI)
-  INSTALL(FILES ${_pyuic_SCRIPTS} DESTINATION ${SALOME_INSTALL_BINS})
+  SALOME_INSTALL_SCRIPTS("${_pyuic_SCRIPTS}" ${SALOME_INSTALL_BINS} TARGET_NAME _target_name_pyuic_py)
+  # add dependency of compiled py files on uic files in order
+  # to avoid races problems when compiling in parallel
+  ADD_DEPENDENCIES(${_target_name_pyuic_py} ${_target_name_pyuic})
 ENDIF(SALOME_BUILD_GUI)
index 07c0275a1dedd07d5b0518c9b03f107e2527874c..1e0cf7b74784405993e97be203738784979ee901 100644 (file)
@@ -22,7 +22,7 @@ INCLUDE(UsePyQt)
 # --- scripts ---
 
 # scripts / static
-SET(plugin_SCRIPTS
+SET(_plugin_SCRIPTS
   maFenetreChoix.py
   monEditor.py
   monNomBase.py
@@ -30,10 +30,8 @@ SET(plugin_SCRIPTS
   __init__.py
 )
 
-# --- resources ---
-
 # uic files / to be processed by pyuic
-SET(_pyuic_files
+SET(_pyuic_FILES
   desFenetreChoix.ui
   desStat.ui
   myMainTotale.ui
@@ -42,12 +40,14 @@ SET(_pyuic_files
   nomBase.ui
   tousLesJobs.ui
 )
-
 # scripts / pyuic wrappings
-PYQT_WRAP_UIC(_pyuic_SCRIPTS ${_pyuic_files})
+PYQT_WRAP_UIC(_pyuic_SCRIPTS ${_pyuic_FILES} TARGET_NAME _target_name_pyuic)
 
 # --- rules ---
 
-SALOME_INSTALL_SCRIPTS("${plugin_SCRIPTS}" ${SALOME_SMESH_INSTALL_PLUGINS}/Verima/Gui)
+SALOME_INSTALL_SCRIPTS("${_plugin_SCRIPTS}" ${SALOME_SMESH_INSTALL_PLUGINS}/Verima/Gui)
 
-SALOME_INSTALL_SCRIPTS("${_pyuic_SCRIPTS}" ${SALOME_SMESH_INSTALL_PLUGINS}/Verima/Gui)
+SALOME_INSTALL_SCRIPTS("${_pyuic_SCRIPTS}" ${SALOME_SMESH_INSTALL_PLUGINS}/Verima/Gui TARGET_NAME _target_name_pyuic_py)
+# add dependency of compiled py files on uic files in order
+# to avoid races problems when compiling in parallel
+ADD_DEPENDENCIES(${_target_name_pyuic_py} ${_target_name_pyuic})
index 7fc73a3b5664ffb5ecdd0a220f9aa34b852cb320..3185f4d63c9bcbb204376b1f2a75665a170a5f4f 100644 (file)
@@ -20,6 +20,7 @@ dicoDimENtite= { 'Entity_Node':0,
 'Entity_Quad_Pyramid':1,
 'Entity_Penta ':1,
 'Entity_Quad_Penta':1,
+'Entity_BiQuad_Penta':1,
 'Entity_Hexagonal_Prism':1,
 'Entity_Polyhedra':1,
 'Entity_Quad_Polyhedra':1,
index 29e6fc99fa22a46d41adc98466990fe8a0e2b108..9ab185c11e930992daf7fb0fcdb5d5ee460ab00c 100644 (file)
@@ -21,30 +21,36 @@ IF(SALOME_BUILD_DOC)
   ADD_SUBDIRECTORY(doc)
 ENDIF(SALOME_BUILD_DOC)
 
-INCLUDE(UsePyQt)
+IF(SALOME_BUILD_GUI)
+  INCLUDE(UsePyQt)
+ENDIF(SALOME_BUILD_GUI)
 
 # --- scripts ---
 
 # scripts / static
-SET(plugin_SCRIPTS
+SET(_plugin_SCRIPTS
   monYamsPlugDialog.py
   monViewText.py
   yamsplug_plugin.py  
 )
 
-# --- resources ---
-
-# uic files / to be processed by pyuic
-SET(_pyuic_files
-  YamsPlugDialog.ui  
-  ViewText.ui
-)
-
-# scripts / pyuic wrappings
-PYQT_WRAP_UIC(_pyuic_SCRIPTS ${_pyuic_files})
+IF(SALOME_BUILD_GUI)
+  # uic files / to be processed by pyuic
+  SET(_pyuic_FILES
+    YamsPlugDialog.ui  
+    ViewText.ui
+  )
+  # scripts / pyuic wrappings
+  PYQT_WRAP_UIC(_pyuic_SCRIPTS ${_pyuic_FILES} TARGET_NAME _target_name_pyuic)
+ENDIF(SALOME_BUILD_GUI)
 
 # --- rules ---
 
-SALOME_INSTALL_SCRIPTS("${plugin_SCRIPTS}" ${SALOME_SMESH_INSTALL_PLUGINS})
+SALOME_INSTALL_SCRIPTS("${_plugin_SCRIPTS}" ${SALOME_SMESH_INSTALL_PLUGINS})
 
-SALOME_INSTALL_SCRIPTS("${_pyuic_SCRIPTS}" ${SALOME_SMESH_INSTALL_PLUGINS})
\ No newline at end of file
+IF(SALOME_BUILD_GUI)
+  SALOME_INSTALL_SCRIPTS("${_pyuic_SCRIPTS}" ${SALOME_SMESH_INSTALL_PLUGINS} TARGET_NAME _target_name_pyuic_py)
+  # add dependency of compiled py files on uic files in order
+  # to avoid races problems when compiling in parallel
+  ADD_DEPENDENCIES(${_target_name_pyuic_py} ${_target_name_pyuic})
+ENDIF(SALOME_BUILD_GUI)
index 23b0385bdb4d6b8c73a86189881a189cbfefc6ee..e0034905b2a2d2c87d6cd2d97b74a2e2c70e8ea0 100644 (file)
@@ -8,7 +8,7 @@ Advanced Remeshing Options
   
 - **Ridge detection**
 if not set (ridge detection disabled ), MeshGems-SurfOpt will not try to detect any new ridge edge by its own mechanism : 
-it will consider as ridge only the ridges given in the mesh.  All non-ridge edges that would have been detected as ridge by the Ridge angle paramaeter (see below split edge)  will be considered as part of the same continuous patch.  This option should not be checked when all the known ridges of the mesh are given and when all other possible ridges are not geometric ridges to take into account.
+it will consider as ridge only the ridges given in the mesh.  All non-ridge edges that would have been detected as ridge by the Ridge angle parameter (see below split edge)  will be considered as part of the same continuous patch.  This option should not be checked when all the known ridges of the mesh are given and when all other possible ridges are not geometric ridges to take into account.
 
 - **Point smoothing**
 When not set (point smoothing is disabled), MeshGems-SurfOpt will not try to move the initial given vertices (along an edge, a ridge or onto the surface), hence MeshGems-SurfOpt will only swap edges, remove vertices or add vertices (refines) to change the mesh.
@@ -34,8 +34,8 @@ These two parameters allow the user to prescribe a Maximal/Minimal size for the
 
 
 - **Mesh gradation**
-This paramater P controls the element size variation : MeshGems-SurfOpt will avoid having two adjacent egdes which sizes vary more than th given gradation. a size correction is applied to the size map : if two adjacent edges are respectively e1 and e2 long and e2 > Pxe1, then, the new size for the second edge will be set to P x e1.
-**This procedure is desactived if P=-1**
+This parameter P controls the element size variation : MeshGems-SurfOpt will avoid having two adjacent egdes which sizes vary more than th given gradation. A size correction is applied to the size map : if two adjacent edges are respectively e1 and e2 long and e2 > Pxe1, then, the new size for the second edge will be set to P x e1.
+**This procedure is deactived if P=-1**
 
 
 
index d4aff8f19a97041ca639dfd438391254b7dd19fe..8d9cf55608b7545674058d6782994218da5ac21c 100644 (file)
@@ -98,7 +98,7 @@ it can be :
   - relative : the maximal chordal deviation - epsilon max - is set to *s x the parameter* where *s* is the size 
     of the bounding box longest diagonal. 
     By default, the parameter is set to 0.001 and the maximum deviation is then set to 0.001 x s,  
-    which is equivalent to say that, for a bouding box of 1 meter, the maximal deviation is 1 mm.
+    which is equivalent to say that, for a bounding box of 1 meter, the maximal deviation is 1 mm.
   - absolute : the maximal chordal deviation is the parameter itself. eg if the parameter equals 2, the maximal chordal deviation will be 2 (mm if the point coordonates are given in mm).
 
 Following that criterion:
index 288b9d7833ca77cc1836a1053f32ea43e6d75239..2f87a5cf195fa35526b0c432df3f9e2493c26665 100644 (file)
 
 ADD_SUBDIRECTORY(casTests)
 
-INCLUDE(UsePyQt)
+IF(SALOME_BUILD_GUI)
+  INCLUDE(UsePyQt)
+ENDIF(SALOME_BUILD_GUI)
 
 # --- scripts ---
 
 # scripts / static
-SET(plugin_SCRIPTS
+SET(_plugin_SCRIPTS
   __init__.py
   ellipse.py
   genereCrack.py
@@ -38,22 +40,27 @@ SET(plugin_SCRIPTS
   Zset.py
 )
 
-SET(command_SCRIPTS
+SET(_command_SCRIPTS
   zcracksLaunch.py
 )
 
-# --- resources ---
-
-# uic files / to be processed by pyuic
-SET(_pyuic_files
-  zcracks.ui
-)
-
-# scripts / pyuic wrappings
-PYQT_WRAP_UIC(_pyuic_SCRIPTS ${_pyuic_files})
+IF(SALOME_BUILD_GUI)
+  # uic files / to be processed by pyuic
+  SET(_pyuic_FILES
+    zcracks.ui
+  )
+  # scripts / pyuic wrappings
+  PYQT_WRAP_UIC(_pyuic_SCRIPTS ${_pyuic_FILES} TARGET_NAME _target_name_pyuic)
+ENDIF(SALOME_BUILD_GUI)
 
 # --- rules ---
 
-SALOME_INSTALL_SCRIPTS("${plugin_SCRIPTS}" ${SALOME_INSTALL_PYTHON}/Zcracks)
-SALOME_INSTALL_SCRIPTS("${_pyuic_SCRIPTS}" ${SALOME_INSTALL_PYTHON}/Zcracks)
-SALOME_INSTALL_SCRIPTS("${command_SCRIPTS}" ${SALOME_INSTALL_BINS})
+SALOME_INSTALL_SCRIPTS("${_plugin_SCRIPTS}" ${SALOME_INSTALL_PYTHON}/Zcracks)
+SALOME_INSTALL_SCRIPTS("${_command_SCRIPTS}" ${SALOME_INSTALL_BINS})
+IF(SALOME_BUILD_GUI)
+  SALOME_INSTALL_SCRIPTS("${_pyuic_SCRIPTS}" ${SALOME_INSTALL_PYTHON}/Zcracks TARGET_NAME _target_name_pyuic_py)
+  # add dependency of compiled py files on uic files in order
+  # to avoid races problems when compiling in parallel
+  ADD_DEPENDENCIES(${_target_name_pyuic_py} ${_target_name_pyuic})
+ENDIF(SALOME_BUILD_GUI)
+
index 8fc299d22f12083a4d7dcead90dc2a61cf9c7516..3de4be60e477578d183960324c3e352e3b01a7c0 100644 (file)
      <item row="2" column="0">
       <widget class="QLabel" name="txtExtractLength">
        <property name="toolTip">
-        <string>Extraction length (optionnal)</string>
+        <string>Extraction length (optional)</string>
        </property>
        <property name="text">
         <string>Extraction length</string>
index 5ba2e6075ca790cd28984c20ab01e4f419cbf039..a561ab8168267243ddab5016f6d712989488c2c4 100644 (file)
@@ -22,7 +22,7 @@ INCLUDE(UsePyQt)
 # --- scripts ---
 
 # scripts / static
-SET(plugin_SCRIPTS
+SET(_plugin_SCRIPTS
   __init__.py
   fissureCoude_ihm.py
   fissureCoude_plugin.py
@@ -30,19 +30,19 @@ SET(plugin_SCRIPTS
   dialogFissureCoude.dic
 )
 
-# --- resources ---
-
 # uic files / to be processed by pyuic
-SET(_pyuic_files
+SET(_pyuic_FILES
   fissureCoude.ui
   fissureGenerale.ui
 )
-
 # scripts / pyuic wrappings
-PYQT_WRAP_UIC(_pyuic_SCRIPTS ${_pyuic_files})
+PYQT_WRAP_UIC(_pyuic_SCRIPTS ${_pyuic_FILES} TARGET_NAME _target_name_pyuic)
 
 # --- rules ---
 
-SALOME_INSTALL_SCRIPTS("${plugin_SCRIPTS}" ${SALOME_INSTALL_PYTHON}/blocFissure/ihm)
+SALOME_INSTALL_SCRIPTS("${_plugin_SCRIPTS}" ${SALOME_INSTALL_PYTHON}/blocFissure/ihm)
 
-SALOME_INSTALL_SCRIPTS("${_pyuic_SCRIPTS}" ${SALOME_INSTALL_PYTHON}/blocFissure/ihm)
+SALOME_INSTALL_SCRIPTS("${_pyuic_SCRIPTS}" ${SALOME_INSTALL_PYTHON}/blocFissure/ihm TARGET_NAME _target_name_pyuic_py)
+# add dependency of compiled py files on uic files in order
+# to avoid races problems when compiling in parallel
+ADD_DEPENDENCIES(${_target_name_pyuic_py} ${_target_name_pyuic})
index 7a77330d808917261ac0d461bb2c51f13bc8b749..9f951022550af9bbb8ccde20c22220fdde98d656 100644 (file)
@@ -371,7 +371,7 @@ CORBA::Long MeshJobManager_i::initialize(const MESHJOB::MeshJobFileList & meshJo
   // Specification of the working spaces:
   //
   // - local_directory: can be used to specify where to find the input
-  //   files on the local resource. It's optionnal if you specify the
+  //   files on the local resource. It's optional if you specify the
   //   absolute path name of input files.
   //
   // - result_directory: must be used to specify where to download the
index 8bffecdc766415a586c836bca184b524dc36a55a..3ee6b8567a09b1fe73312b352f30ee4977d60e0b 100644 (file)
@@ -22,7 +22,7 @@ INCLUDE(UsePyQt)
 # --- scripts ---
 
 # scripts / static
-SET(py_SCRIPTS
+SET(_py_SCRIPTS
   __init__.py
   plugindialog.py
   inputdialog.py
@@ -32,7 +32,7 @@ SET(py_SCRIPTS
 # --- resources ---
 
 # uic files / to be processed by pyuic
-SET(spadderpy_DATA
+SET(_spadderpy_DATA
   parameters.png
   input.png
   select.png
@@ -46,15 +46,20 @@ SET(spadderpy_DATA
   steelbar.png
 )
 
-SET(_pyuic_files
+SET(_pyuic_FILES
   plugindialog.ui
   inputframe.ui
 )
 
 # scripts / pyuic wrappings
-PYQT_WRAP_UIC(_pyuic_SCRIPTS ${_pyuic_files})
+PYQT_WRAP_UIC(_pyuic_SCRIPTS ${_pyuic_FILES} TARGET_NAME _target_name_pyuic)
 
 # --- rules ---
-SALOME_INSTALL_SCRIPTS("${_pyuic_SCRIPTS}" ${SALOME_INSTALL_PYTHON}/salome/smesh/spadder/gui)
-SALOME_INSTALL_SCRIPTS("${py_SCRIPTS}" ${SALOME_INSTALL_PYTHON}/salome/smesh/spadder/gui)
-INSTALL(FILES ${spadderpy_DATA} DESTINATION ${SALOME_INSTALL_PYTHON}/salome/smesh/spadder/gui)
+SALOME_INSTALL_SCRIPTS("${_pyuic_SCRIPTS}" ${SALOME_INSTALL_PYTHON}/salome/smesh/spadder/gui TARGET_NAME _target_name_pyuic_py)
+# add dependency of compiled py files on uic files in order
+# to avoid races problems when compiling in parallel
+ADD_DEPENDENCIES(${_target_name_pyuic_py} ${_target_name_pyuic})
+
+SALOME_INSTALL_SCRIPTS("${_py_SCRIPTS}" ${SALOME_INSTALL_PYTHON}/salome/smesh/spadder/gui)
+
+INSTALL(FILES ${_spadderpy_DATA} DESTINATION ${SALOME_INSTALL_PYTHON}/salome/smesh/spadder/gui)