Salome HOME
Merge branch 'occ/new_mg_licnese'
authorvsr <vsr@opencascade.com>
Fri, 24 Sep 2021 08:54:11 +0000 (11:54 +0300)
committervsr <vsr@opencascade.com>
Fri, 24 Sep 2021 08:54:11 +0000 (11:54 +0300)
135 files changed:
doc/salome/examples/3dmesh.py
doc/salome/examples/CMakeLists.txt
doc/salome/examples/CTestTestfileInstall.cmake
doc/salome/examples/MGAdaptTests_without_session.py
doc/salome/examples/Mesh_tri.med [new file with mode: 0644]
doc/salome/examples/a3DmeshOnModified2Dmesh.py
doc/salome/examples/blocFissure_01_without_session.py [changed mode: 0755->0644]
doc/salome/examples/blocFissure_02_without_session.py [changed mode: 0755->0644]
doc/salome/examples/blocFissure_03_without_session.py [changed mode: 0755->0644]
doc/salome/examples/blocFissure_04_without_session.py [changed mode: 0755->0644]
doc/salome/examples/blocFissure_05_without_session.py [changed mode: 0755->0644]
doc/salome/examples/blocFissure_06_without_session.py [changed mode: 0755->0644]
doc/salome/examples/blocFissure_07_without_session.py [changed mode: 0755->0644]
doc/salome/examples/cartesian_algo.py
doc/salome/examples/create_penta_biquad.py
doc/salome/examples/creating_meshes_ex01.py
doc/salome/examples/creating_meshes_ex02.py
doc/salome/examples/creating_meshes_ex03.py
doc/salome/examples/creating_meshes_ex04.py
doc/salome/examples/creating_meshes_ex05.py
doc/salome/examples/creating_meshes_ex06.py
doc/salome/examples/creating_meshes_ex07.py
doc/salome/examples/creating_meshes_ex08.py
doc/salome/examples/defining_hypotheses_adaptive1d.py
doc/salome/examples/defining_hypotheses_ex01.py
doc/salome/examples/defining_hypotheses_ex02.py
doc/salome/examples/defining_hypotheses_ex03.py
doc/salome/examples/defining_hypotheses_ex04.py
doc/salome/examples/defining_hypotheses_ex05.py
doc/salome/examples/defining_hypotheses_ex06.py
doc/salome/examples/defining_hypotheses_ex07.py
doc/salome/examples/defining_hypotheses_ex08.py
doc/salome/examples/defining_hypotheses_ex09.py
doc/salome/examples/defining_hypotheses_ex10.py
doc/salome/examples/defining_hypotheses_ex11.py
doc/salome/examples/defining_hypotheses_ex12.py
doc/salome/examples/defining_hypotheses_ex13.py
doc/salome/examples/defining_hypotheses_ex14.py
doc/salome/examples/defining_hypotheses_ex15.py
doc/salome/examples/defining_hypotheses_ex16.py
doc/salome/examples/defining_hypotheses_ex17.py
doc/salome/examples/defining_hypotheses_len_near_vertex.py
doc/salome/examples/extrusion_penta_biquad.py
doc/salome/examples/filters_ex09.py
doc/salome/examples/filters_ex10.py
doc/salome/examples/filters_ex16.py
doc/salome/examples/filters_ex17.py
doc/salome/examples/filters_ex18.py
doc/salome/examples/filters_ex39.py
doc/salome/examples/find_salome_actor_delegate_to_vtk.py [new file with mode: 0644]
doc/salome/examples/generate_flat_elements.py
doc/salome/examples/grouping_elements_ex02.py
doc/salome/examples/grouping_elements_ex03.py
doc/salome/examples/grouping_elements_ex09.py
doc/salome/examples/measurements_ex01.py
doc/salome/examples/measurements_ex02.py
doc/salome/examples/measurements_ex03.py
doc/salome/examples/measurements_ex04.py
doc/salome/examples/modifying_meshes_ex01.py
doc/salome/examples/modifying_meshes_ex02.py
doc/salome/examples/modifying_meshes_ex03.py
doc/salome/examples/modifying_meshes_ex09.py
doc/salome/examples/modifying_meshes_ex10.py
doc/salome/examples/modifying_meshes_ex15.py
doc/salome/examples/modifying_meshes_ex16.py
doc/salome/examples/modifying_meshes_ex17.py
doc/salome/examples/modifying_meshes_ex18.py
doc/salome/examples/modifying_meshes_ex19.py
doc/salome/examples/modifying_meshes_ex21.py
doc/salome/examples/modifying_meshes_ex22.py
doc/salome/examples/modifying_meshes_ex23.py
doc/salome/examples/modifying_meshes_ex25.py
doc/salome/examples/modifying_meshes_ex26.py
doc/salome/examples/modifying_meshes_split_vol.py
doc/salome/examples/notebook_smesh.py
doc/salome/examples/prism_3d_algo.py
doc/salome/examples/quad_medial_axis_algo.py
doc/salome/examples/quality_controls_defl.py
doc/salome/examples/quality_controls_ex01.py
doc/salome/examples/quality_controls_ex02.py
doc/salome/examples/quality_controls_ex03.py
doc/salome/examples/quality_controls_ex05.py
doc/salome/examples/quality_controls_ex06.py
doc/salome/examples/quality_controls_ex07.py
doc/salome/examples/quality_controls_ex08.py
doc/salome/examples/quality_controls_ex09.py
doc/salome/examples/quality_controls_ex10.py
doc/salome/examples/quality_controls_ex11.py
doc/salome/examples/quality_controls_ex12.py
doc/salome/examples/radial_prism_3d_algo.py
doc/salome/examples/split_biquad.py
doc/salome/examples/ssl_hdf5_symbols_conflicts.py [new file with mode: 0644]
doc/salome/examples/test_polyhedron_per_solid.py
doc/salome/examples/test_smeshplugin_mg_tetra_parallele.py [changed mode: 0755->0644]
doc/salome/examples/test_smeshplugins.py [changed mode: 0755->0644]
doc/salome/examples/tests.set
doc/salome/examples/transforming_meshes_ex03.py
doc/salome/examples/transforming_meshes_ex06.py
doc/salome/examples/transforming_meshes_ex07.py
doc/salome/examples/transforming_meshes_ex08.py
doc/salome/examples/transforming_meshes_ex09.py
doc/salome/examples/transforming_meshes_ex10.py
doc/salome/examples/transforming_meshes_ex11.py
doc/salome/examples/transforming_meshes_ex12.py
doc/salome/examples/transforming_meshes_ex13.py
doc/salome/examples/use_existing_faces.py
doc/salome/examples/viewing_meshes_ex01.py
doc/salome/examples/viewing_meshes_ex02.py
doc/salome/gui/SMESH/images/ctrlinfo.png
doc/salome/gui/SMESH/images/extrusion_along_path_dlg.png
doc/salome/gui/SMESH/images/extrusionalongaline1.png
doc/salome/gui/SMESH/images/revolution1.png
src/SMESH/MG_ADAPT.cxx
src/SMESHGUI/SMESHGUI.cxx
src/SMESHGUI/SMESHGUI_ExtrusionAlongPathDlg.cxx
src/SMESHGUI/SMESHGUI_ExtrusionDlg.cxx
src/SMESHGUI/SMESHGUI_GEOMGenUtils.cxx
src/SMESHGUI/SMESHGUI_GEOMGenUtils.h
src/SMESHGUI/SMESHGUI_GroupDlg.cxx
src/SMESHGUI/SMESHGUI_GroupDlg.h
src/SMESHGUI/SMESHGUI_GroupOnShapeDlg.cxx
src/SMESHGUI/SMESHGUI_GroupOnShapeDlg.h
src/SMESHGUI/SMESHGUI_MeshInfo.cxx
src/SMESHGUI/SMESHGUI_MeshInfo.h
src/SMESHGUI/SMESHGUI_MeshOp.cxx
src/SMESHGUI/SMESHGUI_RevolutionDlg.cxx
src/SMESHGUI/SMESH_msg_en.ts
src/SMESH_I/SMESH_Gen_No_Session_i.cxx
src/SMESH_I/SMESH_Gen_i.cxx
src/SMESH_I/SMESH_Gen_i_1.cxx
src/SMESH_I/SMESH_PreMeshInfo.cxx
src/SMESH_SWIG/SMESH_mechanic.py
src/SMESH_SWIG/SMESH_mechanic_tetra.py
src/StdMeshers/StdMeshers_Hexa_3D.cxx
src/StdMeshers/StdMeshers_ViscousLayers.cxx

index 04d6073bdb2adb486e8850e0ff6338214ac9c90d..0fdfcb68d5bfe32ad87ad0e5408b0910758c4238 100644 (file)
@@ -1,7 +1,7 @@
 # 3d mesh generation and mesh exploration
 
 import salome
-salome.salome_init()
+salome.salome_init_without_session()
 from salome.geom import geomBuilder
 geompy = geomBuilder.New()
 
index 7ecb2db4a430404664a3edd9bada1cc8d8cdb8d4..df54d5a0840a7e5017a315da81de31a3ba766d8a 100644 (file)
@@ -42,6 +42,7 @@ SALOME_INSTALL_SCRIPTS("${EXAMPLES_TESTS}" ${SALOME_INSTALL_DOC}/examples/SMESH)
 
 SET(TEST_INSTALL_DIRECTORY ${SALOME_INSTALL_SCRIPT_SCRIPTS}/test)
 INSTALL(FILES ${GOOD_TESTS} ${BAD_TESTS} ${SESSION_FREE_TESTS} DESTINATION ${TEST_INSTALL_DIRECTORY})
+INSTALL(FILES Mesh_tri.med DESTINATION ${TEST_INSTALL_DIRECTORY})
 
 INSTALL(FILES CTestTestfileInstall.cmake
         DESTINATION ${TEST_INSTALL_DIRECTORY}
index daf0e0004bd7c913f1e8179662c719aba0151c01..cf70be839e82dde96307f937de4c0687f771108d 100644 (file)
 
 INCLUDE(tests.set)
 
-SET(SALOME_TEST_DRIVER "$ENV{KERNEL_ROOT_DIR}/bin/salome/appliskel/salome_test_driver.py")
+SET(PYTHON_TEST_DRIVER "$ENV{KERNEL_ROOT_DIR}/bin/salome/appliskel/python_test_driver.py")
 SET(COMPONENT_NAME SMESH)
 SET(TIMEOUT        300)
 
 FOREACH(tfile ${GOOD_TESTS} ${BAD_TESTS})
   GET_FILENAME_COMPONENT(BASE_NAME ${tfile} NAME_WE)
   SET(TEST_NAME SMESH_${BASE_NAME})
-  ADD_TEST(${TEST_NAME} python ${SALOME_TEST_DRIVER} ${TIMEOUT} ${tfile})
+  ADD_TEST(${TEST_NAME} python ${PYTHON_TEST_DRIVER} ${TIMEOUT} ${tfile})
   SET_TESTS_PROPERTIES(${TEST_NAME} PROPERTIES LABELS "${COMPONENT_NAME}")
 ENDFOREACH()
 
index 4855345c1de4478c93c08435968c9f0107a14d97..2f0621d703125b2472c63c0893e1231f25d939a5 100644 (file)
@@ -16,7 +16,7 @@ import os
 import salome
 
 salome.standalone()
-salome.salome_init()
+salome.salome_init_without_session()
 
 import SMESH
 from salome.smesh import smeshBuilder
@@ -450,7 +450,7 @@ if __name__ == "__main__" :
   L_OPTIONS.append("05")
   L_OPTIONS.append("06")
   L_OPTIONS.append("08")
-  #L_OPTIONS.append("13")
+  L_OPTIONS.append("13")
 
 # 2. Lancement de la classe
 
diff --git a/doc/salome/examples/Mesh_tri.med b/doc/salome/examples/Mesh_tri.med
new file mode 100644 (file)
index 0000000..e5a1984
Binary files /dev/null and b/doc/salome/examples/Mesh_tri.med differ
index ae03906c89068e7861633390ead318d182009078..fb49f873c8b79525782bc063b1129dd9ec460592 100644 (file)
@@ -1,5 +1,5 @@
 import salome
-salome.salome_init()
+salome.salome_init_without_session()
 
 from salome.geom import geomBuilder
 geompy = geomBuilder.New()
old mode 100755 (executable)
new mode 100644 (file)
index fcdda32..14c186f
@@ -19,7 +19,7 @@ import sys
 # Lancement des cas-tests
 import salome
 salome.standalone()
-salome.salome_init()
+salome.salome_init_without_session()
 
 from blocFissure.CasTests.blocFissureTest import blocFissureTest
 BLOCFISSURE_TEST = blocFissureTest(["cubeAngle", "cubeAngle_2","cubeCoin", "cubeMilieu", "cubeTransverse"])
old mode 100755 (executable)
new mode 100644 (file)
index 72700e3..49e0e83
@@ -22,7 +22,7 @@ import sys
 # Lancement des cas-tests
 import salome
 salome.standalone()
-salome.salome_init()
+salome.salome_init_without_session()
 
 from blocFissure.CasTests.blocFissureTest import blocFissureTest
 BLOCFISSURE_TEST = blocFissureTest(["cylindre", "cylindre_2", "disquePerce", "faceGauche","ellipse_1", "ellipse_2"])
old mode 100755 (executable)
new mode 100644 (file)
index a6f730c..2b2f8ad
@@ -19,7 +19,7 @@ import sys
 # Lancement des cas-tests
 import salome
 salome.standalone()
-salome.salome_init()
+salome.salome_init_without_session()
 
 from blocFissure.CasTests.blocFissureTest import blocFissureTest
 BLOCFISSURE_TEST = blocFissureTest(["eprouvetteCourbe", "eprouvetteDroite", "eprouvetteDroite_2"])
old mode 100755 (executable)
new mode 100644 (file)
index e535f76..0474743
@@ -17,7 +17,7 @@ import sys
 # Lancement des cas-tests
 import salome
 salome.standalone()
-salome.salome_init()
+salome.salome_init_without_session()
 
 from blocFissure.CasTests.blocFissureTest import blocFissureTest
 BLOCFISSURE_TEST = blocFissureTest(["fissureCoude_1", "fissureCoude_2", "fissureCoude_3", "fissureCoude_4", "fissureCoude_5"])
old mode 100755 (executable)
new mode 100644 (file)
index 16e4bb3..b86a2ee
@@ -17,7 +17,7 @@ import sys
 # Lancement des cas-tests
 import salome
 salome.standalone()
-salome.salome_init()
+salome.salome_init_without_session()
 
 from blocFissure.CasTests.blocFissureTest import blocFissureTest
 BLOCFISSURE_TEST = blocFissureTest(["fissureCoude_6", "fissureCoude_7", "fissureCoude_8", "fissureCoude_9", "fissureCoude_10"])
old mode 100755 (executable)
new mode 100644 (file)
index 185f5d7..fd2ef82
@@ -17,7 +17,7 @@ import sys
 # Lancement des cas-tests
 import salome
 salome.standalone()
-salome.salome_init()
+salome.salome_init_without_session()
 
 from blocFissure.CasTests.blocFissureTest import blocFissureTest
 BLOCFISSURE_TEST = blocFissureTest(["fissure_Coude", "fissure_Coude_4"])
old mode 100755 (executable)
new mode 100644 (file)
index 87ff982..d4d3836
@@ -19,7 +19,7 @@ import sys
 # Lancement des cas-tests
 import salome
 salome.standalone()
-salome.salome_init()
+salome.salome_init_without_session()
 
 from blocFissure.CasTests.blocFissureTest import blocFissureTest
 BLOCFISSURE_TEST = blocFissureTest(["vis_1"])
index d7d64b8b7617bfbb8e813f812b52ea0509b3cb1e..da86cf423500e12862eb699e8d5aee7be593e182 100644 (file)
@@ -2,7 +2,7 @@
 
 
 import salome
-salome.salome_init()
+salome.salome_init_without_session()
 import GEOM
 from salome.geom import geomBuilder
 geompy = geomBuilder.New()
index 9e7ec271a1c5d761d95327f61aa50ce891cc11da..c13f25c38bd93d6384c140d3919e495279db6338 100644 (file)
@@ -3,7 +3,7 @@
 import sys
 import salome
 
-salome.salome_init()
+salome.salome_init_without_session()
 
 import  SMESH, SALOMEDS
 from salome.smesh import smeshBuilder
index 110f6269a74f09e989e2ce0c5f45812af502f25e..ba8563d6d6ae6a2ba253eb01d9e24ea5fdab4963 100644 (file)
@@ -1,7 +1,7 @@
 # Construction of a Mesh
 
 import salome
-salome.salome_init()
+salome.salome_init_without_session()
 import GEOM
 from salome.geom import geomBuilder
 geompy = geomBuilder.New()
index 522f72bf4c1d05a2d0fd6e7d27618766e5d7ccb7..8a8966a3fd5a59c62431440cb6fd74adf52110b2 100644 (file)
@@ -1,7 +1,7 @@
 # Construction of a Sub-mesh
 
 import salome
-salome.salome_init()
+salome.salome_init_without_session()
 import GEOM
 from salome.geom import geomBuilder
 geompy = geomBuilder.New()
index 42bf8c91a40b10a63def6afdb76b89f9b6528c4e..fc20d36608bddef585b768c0413720f662eb581a 100644 (file)
@@ -1,7 +1,7 @@
 # Change priority of sub-meshes in Mesh
 
 import salome
-salome.salome_init()
+salome.salome_init_without_session()
 import GEOM
 from salome.geom import geomBuilder
 geompy = geomBuilder.New()
index 0a3cc9faf13f710919c02622eb7f73b3124a7028..7101a0226c8860318629c6d62dee41c004acf00c 100644 (file)
@@ -1,7 +1,7 @@
 # Editing of a mesh
 
 import salome
-salome.salome_init()
+salome.salome_init_without_session()
 import GEOM
 from salome.geom import geomBuilder
 geompy = geomBuilder.New()
index 08e8d135fb52cf96044921a2fe593b07f54ca75f..725c7e953acdf94250f86b575162fc53e14b4c9c 100644 (file)
@@ -1,7 +1,7 @@
 # Export of a Mesh
 
 import salome
-salome.salome_init()
+salome.salome_init_without_session()
 import GEOM
 from salome.geom import geomBuilder
 geompy = geomBuilder.New()
index 20b8a043446a54a3dc776bd14da8e30e976c769e..60360e14bf6ee6e7cdce8167181c5ab878f0656f 100644 (file)
@@ -5,7 +5,7 @@
 # command creating a blocked cylinder: geompy.MakeDividedCylinder()
 
 import salome
-salome.salome_init()
+salome.salome_init_without_session()
 import GEOM
 from salome.geom import geomBuilder
 geompy = geomBuilder.New()
index 669c9b088b3f0c847566f8f8e43c5bff94f8ffb4..f18109cda9e428b8a189eb461b5534e197abe3bf 100644 (file)
@@ -1,7 +1,7 @@
 # Building a compound of meshes
 
 import salome
-salome.salome_init()
+salome.salome_init_without_session()
 from salome.geom import geomBuilder
 geompy = geomBuilder.New()
 from salome.smesh import smeshBuilder
index ff41f09c65ab6f8a2ef59520cb88bf62a07c40fa..2f506fa2b86a99d01077fce0e2ae4adad8770ba3 100644 (file)
@@ -1,7 +1,7 @@
 # Mesh Copying
 
 import salome
-salome.salome_init()
+salome.salome_init_without_session()
 import GEOM
 from salome.geom import geomBuilder
 geompy = geomBuilder.New()
index 579d14de5fc5eb1b7db98e7c1c76160f73ede789..48d927daa1a21fe71c6ceedf7743c5b939c46eaa 100644 (file)
@@ -1,5 +1,5 @@
 import salome, math
-salome.salome_init()
+salome.salome_init_without_session()
 from salome.geom import geomBuilder
 geompy = geomBuilder.New()
 from salome.smesh import smeshBuilder
index a4083ba4934b66f69906f097d3c8b50f7930e2fd..0a2401d524b6f64b2fcf6e518f8fd3bae8cc1aaf 100644 (file)
@@ -1,7 +1,7 @@
 # Arithmetic Progression and Geometric Progression
 
 import salome
-salome.salome_init()
+salome.salome_init_without_session()
 
 from salome.geom import geomBuilder
 geompy = geomBuilder.New()
index 9473354b3733b2a868c419dba5ea758f85a2400d..c5a5ce205706caa382e9592b21d67a8d5fc84127 100644 (file)
@@ -1,7 +1,7 @@
 # Deflection and Number of Segments
 
 import salome
-salome.salome_init()
+salome.salome_init_without_session()
 import GEOM
 from salome.geom import geomBuilder
 geompy = geomBuilder.New()
index 3e0a5a7defa0305b8bcab7b0047620395c899adf..14af89e197630c66ec1f377338a46ab528f30931 100644 (file)
@@ -1,7 +1,7 @@
 # Start and End Length
 
 import salome
-salome.salome_init()
+salome.salome_init_without_session()
 import GEOM
 from salome.geom import geomBuilder
 geompy = geomBuilder.New()
index c15e4421bf2fc0cc7efb69216994f9e43b379fcb..bb38eeb9d07857d2857ef76a60a6a12baff77716 100644 (file)
@@ -1,7 +1,7 @@
 # Local Length
 
 import salome
-salome.salome_init()
+salome.salome_init_without_session()
 import GEOM
 from salome.geom import geomBuilder
 geompy = geomBuilder.New()
index d998447184cc5e6efb400c60ddd83273584d5ac9..25fe5429f168a945338af53e5dbcc7857976e15b 100644 (file)
@@ -1,7 +1,7 @@
 # Maximum Element Area
 
 import salome
-salome.salome_init()
+salome.salome_init_without_session()
 import GEOM
 from salome.geom import geomBuilder
 geompy = geomBuilder.New()
index f0a02aee40a678cce4934509b6c000e6fe425ef7..687de13f7e6c3e3b5597363b3f57e26a2ced9ffc 100644 (file)
@@ -1,7 +1,7 @@
 # Maximum Element Volume
 
 import salome
-salome.salome_init()
+salome.salome_init_without_session()
 import GEOM
 from salome.geom import geomBuilder
 geompy = geomBuilder.New()
index a8a8e9fd2ef9041241ca9c921836f87fd4b4a952..2beb838d2ea3a70e5af62134cef48b91566f7657 100644 (file)
@@ -1,7 +1,7 @@
 # Length from Edges
 
 import salome
-salome.salome_init()
+salome.salome_init_without_session()
 import GEOM
 from salome.geom import geomBuilder
 geompy = geomBuilder.New()
index 285eae2ad63f29e0c67f65e220dfad39d51f241f..ee0af391231b750ca1eb0458e7d2bf08b02dda1f 100644 (file)
@@ -1,7 +1,7 @@
 # Propagation
 
 import salome
-salome.salome_init()
+salome.salome_init_without_session()
 import GEOM
 from salome.geom import geomBuilder
 geompy = geomBuilder.New()
index 6e86cc95ea7c7bf6d955c4a5a94610d500cb713e..7ac2a0fb4be2c781670b357cff1b12aa87d2965f 100644 (file)
@@ -1,7 +1,7 @@
 # Defining Meshing Algorithms
 
 import salome
-salome.salome_init()
+salome.salome_init_without_session()
 import GEOM
 from salome.geom import geomBuilder
 geompy = geomBuilder.New()
index c55af79dfcd13ab87caea8a868fafd0529a07f00..0801c2cfc6add725360171eee220408b1dacb09c 100644 (file)
@@ -3,7 +3,7 @@
 # Project prisms from one meshed box to another mesh on the same box
 
 import salome
-salome.salome_init()
+salome.salome_init_without_session()
 import GEOM
 from salome.geom import geomBuilder
 geompy = geomBuilder.New()
index a57d0781dd5784c335893ca02d172433589e2f43..5e85222adda76f3d245eaa83f6b837e9a350cd4d 100644 (file)
@@ -3,7 +3,7 @@
 # Project triangles from one meshed face to another mesh on the same box
 
 import salome
-salome.salome_init()
+salome.salome_init_without_session()
 import GEOM
 from salome.geom import geomBuilder
 geompy = geomBuilder.New()
index 7ead18cbf3b81ea45db38ee1e4afdaf27c683198..9db644836d4ce9fe5e22ed71eed4e1caf653d5f4 100644 (file)
@@ -1,7 +1,7 @@
 # 1D Mesh with Fixed Points example
 
 import salome
-salome.salome_init()
+salome.salome_init_without_session()
 import GEOM
 from salome.geom import geomBuilder
 geompy = geomBuilder.New()
index e952460016a7f4ef6d1eb14a414693ad1dd05d8d..c7c736cff55832dae27ac466bee72994eb6b46a1 100644 (file)
@@ -1,7 +1,7 @@
 # Radial Quadrangle 1D-2D example
 
 import salome
-salome.salome_init()
+salome.salome_init_without_session()
 import GEOM
 from salome.geom import geomBuilder
 geompy = geomBuilder.New()
index d33e1e155e87cd5481f661c08c2a35cbb34a53e9..f1e7e39f39555be2b0684e29340021eb11949e2e 100644 (file)
@@ -1,7 +1,7 @@
 # Quadrangle Parameters example 1 (meshing a face with 3 edges)
 
 import salome
-salome.salome_init()
+salome.salome_init_without_session()
 
 from salome.geom import geomBuilder
 geompy = geomBuilder.New()
index 5a32a1da5f460495534fccfbe1431da1748b3b47..7b0cfbaa45aac528d52ad60cfef7281cf7c0ef58 100644 (file)
@@ -1,7 +1,7 @@
 # Quadrangle Parameters example 2 (using different types)
 
 import salome
-salome.salome_init()
+salome.salome_init_without_session()
 from salome.geom import geomBuilder
 geompy = geomBuilder.New()
 from salome.smesh import smeshBuilder
index 575601f1ef18da00b548e86878f3112c6ef8ad9d..2826aa15ed134788525fa3802594ebfe91087d4a 100644 (file)
@@ -1,7 +1,7 @@
 # "Import 2D Elements from Another Mesh" example
 
 import salome
-salome.salome_init()
+salome.salome_init_without_session()
 import GEOM
 from salome.geom import geomBuilder
 geompy = geomBuilder.New()
index cadd71e24b0af4b1845677b98dc14820ee67e8d0..da76f22101888ff1477710d7fc81feaa4a907644 100644 (file)
@@ -1,7 +1,7 @@
 # Viscous layers construction
 
 import salome
-salome.salome_init()
+salome.salome_init_without_session()
 import GEOM
 from salome.geom import geomBuilder
 geompy = geomBuilder.New()
index 6d8ab44b2e4a9ce7fce6247b4de3d1bf60a8e639..62379eb8e5b35ce756b4f2bed0f9a407a65d9c30 100644 (file)
@@ -3,7 +3,7 @@
 # for meshing a box with quadrangles with refinement near vertices
 
 import salome
-salome.salome_init()
+salome.salome_init_without_session()
 from salome.geom import geomBuilder
 geompy = geomBuilder.New()
 from salome.smesh import smeshBuilder
index b98f8cd4bbdd0c739446f59dfa4fef9f23ef9969..fb50008a9c958f83b87525ca186e9d1665a73dc6 100644 (file)
@@ -3,7 +3,7 @@
 import sys
 import salome
 
-salome.salome_init()
+salome.salome_init_without_session()
 
 import GEOM
 from salome.geom import geomBuilder
index 21c1d6c94795c94b828fc8b1e1c75b238c366528..8e2ebfd3d41565119623ba165c2e5dfdea09a9da 100644 (file)
@@ -2,7 +2,7 @@
 
 # initialize SALOME and modules
 import salome, SMESH
-salome.salome_init()
+salome.salome_init_without_session()
 from salome.geom import geomBuilder
 geompy = geomBuilder.New()
 from salome.smesh import smeshBuilder
index d1f5023eb70ad4b36ea6b7600a54946da225fdf6..b90e5188ffb66c1790f84410284475987c75d309 100644 (file)
@@ -2,7 +2,7 @@
 
 # initialize SALOME and modules
 import salome, SMESH
-salome.salome_init()
+salome.salome_init_without_session()
 from salome.geom import geomBuilder
 geompy = geomBuilder.New()
 from salome.smesh import smeshBuilder
index e417ca2fa31d8d08a0335f8f4ee115b50ca503ea..4e3d27be4f3da499d35962d82c369ac145bfb030 100644 (file)
@@ -2,7 +2,7 @@
 
 
 import salome
-salome.salome_init()
+salome.salome_init_without_session()
 import GEOM
 from salome.geom import geomBuilder
 geompy = geomBuilder.New()
index a05fbaa210792c2386ba139c3efd56e3eab5df11..83eda322ce3e8ac88d09231da66a4b1a3c46eb5b 100644 (file)
@@ -1,7 +1,7 @@
 # Double nodes
 
 import salome
-salome.salome_init()
+salome.salome_init_without_session()
 from salome.geom import geomBuilder
 geompy = geomBuilder.New()
 import SMESH
index 6fcba2650c1bc4c0f2f038d4153bdfc8e49eb5f1..c4ec48107860b10f07fe95db5c79601b66f08b72 100644 (file)
@@ -1,7 +1,7 @@
 # Borders at multi-connection
 
 import salome
-salome.salome_init()
+salome.salome_init_without_session()
 from salome.geom import geomBuilder
 geompy = geomBuilder.New()
 import SMESH
index 6a2ddd5077618c33daeec7572df1b237191d01ae..52de1c3d7cb20cf71112412a4984d75cf80b9a10 100644 (file)
@@ -1,7 +1,7 @@
 # "Elements of a domain" filter and "Renumber" hypothesis
 
 import salome, SMESH
-salome.salome_init()
+salome.salome_init_without_session()
 from salome.geom import geomBuilder
 geompy = geomBuilder.New()
 from salome.smesh import smeshBuilder
diff --git a/doc/salome/examples/find_salome_actor_delegate_to_vtk.py b/doc/salome/examples/find_salome_actor_delegate_to_vtk.py
new file mode 100644 (file)
index 0000000..df8dd13
--- /dev/null
@@ -0,0 +1,9 @@
+
+
+# Find if SALOME_ACTOR_DELEGATE_TO_VTK is activated
+
+import os
+import sys
+
+if 'SALOME_ACTOR_DELEGATE_TO_VTK' not in os.environ:
+    raise RuntimeError('SALOME_ACTOR_DELEGATE_TO_VTK is not set!')
index 5dda5bb7a68a9785e235ea075cf5cb24a406497f..d14cb0495a39de07d8f1aaf082f0d151039819a2 100644 (file)
@@ -5,7 +5,7 @@
 
 
 import salome
-salome.salome_init()
+salome.salome_init_without_session()
 import GEOM
 from salome.geom import geomBuilder
 geompy = geomBuilder.New()
index 4e2a4957f763ca1625c2312af6b021bcfc599a04..16feda41f398d0e66f1fe224aad488662665a619 100644 (file)
@@ -2,7 +2,7 @@
 
 
 import salome
-salome.salome_init()
+salome.salome_init_without_session()
 import GEOM
 from salome.geom import geomBuilder
 geompy = geomBuilder.New()
index 97e1de9452eeb98d66c192f2e8e4623fc050d94a..d6d6e83d9a19c25c362788ff5687b654e80b0a55 100644 (file)
@@ -2,7 +2,7 @@
 
 
 import salome
-salome.salome_init()
+salome.salome_init_without_session()
 import GEOM
 from salome.geom import geomBuilder
 geompy = geomBuilder.New()
index e066dbd1ef2e884e82987809c8eb63f18e5a4745..988dad3cfed6332ef384a8efde055f3e95811882 100644 (file)
@@ -1,7 +1,7 @@
 # Creating groups of faces separated by sharp edges
 
 import salome
-salome.salome_init()
+salome.salome_init_without_session()
 from salome.geom import geomBuilder
 from salome.smesh import smeshBuilder
 geompy = geomBuilder.New()
index b94f59cbb8d5411fb9ecb9942966a1c855202e29..b8ccae02ab84426daa0019d34e77c993eb958ab0 100644 (file)
@@ -1,7 +1,7 @@
 # Minimum Distance
 
 import salome
-salome.salome_init()
+salome.salome_init_without_session()
 import GEOM
 from salome.geom import geomBuilder
 geompy = geomBuilder.New()
index a11a47dfb5a98f24d9d6c420df51385730c4f262..20c04bcc832e86ca1a1802ac19fa737a606cb74f 100644 (file)
@@ -2,7 +2,7 @@
 
 
 import salome
-salome.salome_init()
+salome.salome_init_without_session()
 import GEOM
 from salome.geom import geomBuilder
 geompy = geomBuilder.New()
index d936878835d43670e5d6ad16572b900e5089c9b9..217d9cb2352ca3bfdd88e1cd5e7716685aa21799 100644 (file)
@@ -2,7 +2,7 @@
 
 
 import salome
-salome.salome_init()
+salome.salome_init_without_session()
 import GEOM
 from salome.geom import geomBuilder
 geompy = geomBuilder.New()
index 6524ac97a6617c9693cfdacf246318c857bb4656..b143267ba0178932707e933e20c9ef234014492e 100644 (file)
@@ -2,7 +2,7 @@
 
 
 import salome
-salome.salome_init()
+salome.salome_init_without_session()
 from salome.smesh import smeshBuilder
 smesh =  smeshBuilder.New()
 
index 5950a00cf209b292b0df13f6b50bc7914a341d02..2214610cb55619eebc4f994efa6cb0089f946268 100644 (file)
@@ -1,7 +1,7 @@
 # Add Node
 
 import salome
-salome.salome_init()
+salome.salome_init_without_session()
 
 from salome.smesh import smeshBuilder
 smesh =  smeshBuilder.New()
index 78aff713cea8aac31396febc5023f18023115f70..7b0b9f3481871b15f5c0d80cf71ef760f586bade 100644 (file)
@@ -1,7 +1,7 @@
 # Add 0D Element
 
 import salome
-salome.salome_init()
+salome.salome_init_without_session()
 
 from salome.smesh import smeshBuilder
 smesh =  smeshBuilder.New()
index 46df84e8f84176444d451100e1e188c49986189d..59198ccd62efec45e9687752ff8442abe3f8a5cb 100644 (file)
@@ -2,7 +2,7 @@
 
 
 import salome
-salome.salome_init()
+salome.salome_init_without_session()
 
 from salome.geom import geomBuilder
 geompy = geomBuilder.New()
index 057a5d6a2d1852974bf0ff11a9c409b2d90a5509..914e91b5b20978cc7dee85bc00fbb5fd75cec337 100644 (file)
@@ -1,7 +1,7 @@
 # Add Polygon
 
 import salome
-salome.salome_init()
+salome.salome_init_without_session()
 
 import SMESH, SALOMEDS
 from salome.smesh import smeshBuilder
index fe8ec68c6d887954a4dcc65744e531705d8e9a19..ed49c4fa690b206f6a23eb5203b9e8526ec5b59d 100644 (file)
@@ -2,7 +2,7 @@
 
 
 import salome
-salome.salome_init()
+salome.salome_init_without_session()
 
 from salome.smesh import smeshBuilder
 smesh =  smeshBuilder.New()
index 2656ea300bc2d625d2cb0ca2cc4ccfece26793ca..7d62245e8768bc03df600b30cc0c7a892d8e98eb 100644 (file)
@@ -2,7 +2,7 @@
 
 
 import salome
-salome.salome_init()
+salome.salome_init_without_session()
 
 from salome.geom import geomBuilder
 geompy = geomBuilder.New()
index 2ecc4ed079a6690efc2d11050f9083ed5521340c..82bd0e0cf9eed13d15d14a1ab0027f6ea55bf2c6 100644 (file)
@@ -2,7 +2,7 @@
 
 
 import salome
-salome.salome_init()
+salome.salome_init_without_session()
 import GEOM
 from salome.geom import geomBuilder
 geompy = geomBuilder.New()
index 1fe0c466bf63780b0a2316fdd73475aa178ffa1b..833c5027f51df92b05102b5f7c4c9c977de3877f 100644 (file)
@@ -2,7 +2,7 @@
 
 
 import salome
-salome.salome_init()
+salome.salome_init_without_session()
 import GEOM
 from salome.geom import geomBuilder
 geompy = geomBuilder.New()
index fd21b376e0919185c8604365e73584a33b463c7b..738e8d21384a715c5bdcc0eee23157fa4b4c9ec6 100644 (file)
@@ -2,7 +2,7 @@
 
 
 import salome
-salome.salome_init()
+salome.salome_init_without_session()
 import GEOM
 from salome.geom import geomBuilder
 geompy = geomBuilder.New()
index 7e3c723c52ea956c7da551804b924b0e0f0f7da2..386a3cb56cb84a0a38969f8ff3b04c7f5d9acb03 100644 (file)
@@ -2,7 +2,7 @@
 
 
 import salome
-salome.salome_init()
+salome.salome_init_without_session()
 import GEOM
 from salome.geom import geomBuilder
 geompy = geomBuilder.New()
index a2b92a9f9015419f7f2cff1e00e84c8a8f4ecf9d..6aa3f230de64dfffd3db54dbbf4fa0c4c58bfbb3 100644 (file)
@@ -2,7 +2,7 @@
 
 
 import salome
-salome.salome_init()
+salome.salome_init_without_session()
 import GEOM
 from salome.geom import geomBuilder
 geompy = geomBuilder.New()
index fe99d13e3cd757e3f02741ee3524c5799ab9bcd5..94ce7561d26bb9daa5ebac75bc955dcdc85cd657 100644 (file)
@@ -4,7 +4,7 @@
 # a fully functional method is ExtrusionSweepObjects()
 
 import salome, math
-salome.salome_init()
+salome.salome_init_without_session()
 from salome.geom import geomBuilder
 geompy = geomBuilder.New()
 
index d7f413440df5108c465d6e94acdcaa34790443fe..d2f52b229f80a341941f521077fe3284c25683fa 100644 (file)
@@ -3,7 +3,7 @@
 import math
 
 import salome
-salome.salome_init()
+salome.salome_init_without_session()
 import GEOM
 from salome.geom import geomBuilder
 geompy = geomBuilder.New()
index 82af9b1874cb5b465cec59dc243c908c930b1ba0..7a6804b062f32a20f80d6539eb1fcbc2112be41e 100644 (file)
@@ -2,7 +2,7 @@
 
 
 import salome
-salome.salome_init()
+salome.salome_init_without_session()
 import GEOM
 from salome.geom import geomBuilder
 geompy = geomBuilder.New()
index 53059ff96c9f7f7c7edba2ae0b2649264511809e..defd6ba1d0d45c08fb31e459aef46d91860947b1 100644 (file)
@@ -2,7 +2,7 @@
 
 
 import salome
-salome.salome_init()
+salome.salome_init_without_session()
 import GEOM
 from salome.geom import geomBuilder
 geompy = geomBuilder.New()
index 38e8601b377e2bafbcb27daa02362321e142ab7a..35eea6aabf977b0b844012b26db019a03a10ee63 100644 (file)
@@ -1,7 +1,7 @@
 # Split volumic elements into tetrahedrons
 
 import salome
-salome.salome_init()
+salome.salome_init_without_session()
 
 from salome.geom import geomBuilder
 geompy = geomBuilder.New()
index 376e511634196636a6b61f2bb1a6e53e0a1d0e83..959cc20bdbe8a93cd481917f20534eba6634026c 100644 (file)
@@ -2,7 +2,7 @@
 
 
 import salome
-salome.salome_init()
+salome.salome_init_without_session()
 import GEOM
 from salome.geom import geomBuilder
 geompy = geomBuilder.New()
index 6c2a9d6d4bdef5762011b559d796a4d767b08c79..06a2c5cc239c36166f6df60cc2fe32f3eebaf586 100644 (file)
@@ -1,7 +1,7 @@
 # Usage of Extrusion 3D meshing algorithm
 
 import salome
-salome.salome_init()
+salome.salome_init_without_session()
 
 from salome.geom import geomBuilder
 geompy = geomBuilder.New()
index 42aea882e2fd7e8808f145be44ece0441fc7c727..5937d03acc061913ba9e9c9dc14f1b84645ff090 100644 (file)
@@ -3,7 +3,7 @@
 # for meshing a ring face with quadrangles
 
 import salome
-salome.salome_init()
+salome.salome_init_without_session()
 from salome.geom import geomBuilder
 geompy = geomBuilder.New()
 from salome.smesh import smeshBuilder
index 9c018e8ded479b58cd8746fc9127458c389406d2..97553e02fe47458af6b2288ea2763398cd6cfb1d 100644 (file)
@@ -2,7 +2,7 @@
 
 
 import salome
-salome.salome_init()
+salome.salome_init_without_session()
 from salome.geom import geomBuilder
 geompy = geomBuilder.New()
 
index 30648a3ce6fcd3aab297c29f5743fa7be0c8f991..2cb3c97fc1b284082a8b163ce3f541e042c79d78 100644 (file)
@@ -2,7 +2,7 @@
 
 
 import salome
-salome.salome_init()
+salome.salome_init_without_session()
 import GEOM
 from salome.geom import geomBuilder
 geompy = geomBuilder.New()
index 62a312ca7ed293bae7a1fbf5401b63a4f7c2b094..c0394201033018c47d67b852512effdb516b76eb 100644 (file)
@@ -2,7 +2,7 @@
 
 
 import salome
-salome.salome_init()
+salome.salome_init_without_session()
 import GEOM
 from salome.geom import geomBuilder
 geompy = geomBuilder.New()
index fca52fddf3a1b9ad5e7472efdff5aa66b9f8c056..65db46bbf3df0dc1d212f34588ac301a6815afeb 100644 (file)
@@ -2,7 +2,7 @@
 
 
 import salome
-salome.salome_init()
+salome.salome_init_without_session()
 import GEOM
 from salome.geom import geomBuilder
 geompy = geomBuilder.New()
index 1ec552f752896f40d3c7bccc26f7ab1a2742cc2d..b01e35cae1a6d0dcd44785cda7454ef5b5af4342 100644 (file)
@@ -2,7 +2,7 @@
 
 
 import salome
-salome.salome_init()
+salome.salome_init_without_session()
 import GEOM
 from salome.geom import geomBuilder
 geompy = geomBuilder.New()
index 8dd8e9cf6b2846c9864ca882eccc5ee0a522cf11..c0cecd4b0fef3644ccee32d12deaa2a1ce9e7983 100644 (file)
@@ -2,7 +2,7 @@
 
 
 import salome
-salome.salome_init()
+salome.salome_init_without_session()
 import GEOM
 from salome.geom import geomBuilder
 geompy = geomBuilder.New()
index e85b27d73c86131637c50a359b4a6969c6457a09..d7f29654656bde82a7ae761f9b732b38fce7c2ca 100644 (file)
@@ -2,7 +2,7 @@
 
 
 import salome
-salome.salome_init()
+salome.salome_init_without_session()
 import GEOM
 from salome.geom import geomBuilder
 geompy = geomBuilder.New()
index 157bf5f8cafd7ddf592d1ba3ba6c81ce0a615c86..8fc367ea026e45273e8587e209d4bf2d324b5e12 100644 (file)
@@ -2,7 +2,7 @@
 
 
 import salome
-salome.salome_init()
+salome.salome_init_without_session()
 import GEOM
 from salome.geom import geomBuilder
 geompy = geomBuilder.New()
index 82050cbc0b6e711546246267aff19e16e4f086f6..9f4f7dbad260a078e57a23ca596a36a86ed78d4d 100644 (file)
@@ -2,7 +2,7 @@
 
 
 import salome
-salome.salome_init()
+salome.salome_init_without_session()
 import GEOM
 from salome.geom import geomBuilder
 geompy = geomBuilder.New()
index 1a4287fc7211463e9c1a46295012263b7cd39227..22e93c9b51ec20cfb37fb44056d0d4d73b5aad25 100644 (file)
@@ -2,7 +2,7 @@
 
 
 import salome
-salome.salome_init()
+salome.salome_init_without_session()
 import GEOM
 from salome.geom import geomBuilder
 geompy = geomBuilder.New()
index 7c00278dcf1e5f112a4c9d21c28936a838733356..fbc2b7c5f8405019607da8f561825eeeca44d8b8 100644 (file)
@@ -2,7 +2,7 @@
 
 
 import salome
-salome.salome_init()
+salome.salome_init_without_session()
 import GEOM
 from salome.geom import geomBuilder
 geompy = geomBuilder.New()
index adedda57db5b67a462ca8f674b8304f6bcaeb43c..f6227793cc96daa68809abd7427ea353e6f0f25d 100644 (file)
@@ -2,7 +2,7 @@
 
 
 import salome
-salome.salome_init()
+salome.salome_init_without_session()
 import GEOM
 from salome.geom import geomBuilder
 geompy = geomBuilder.New()
index 6e8c7adba50a29e61894d1945626ae0f93e54e64..fe29e52dcdf592693d00098976be6d6acff5879c 100644 (file)
@@ -1,7 +1,7 @@
 # Usage of Radial Prism 3D meshing algorithm
 
 import salome
-salome.salome_init()
+salome.salome_init_without_session()
 from salome.geom import geomBuilder
 geompy = geomBuilder.New()
 import SMESH
index 235d491578e2221f975263a08a14a2c6d0dfce98..f9d97b31ae8d3b390a06cab4a2da50c1c6c56df5 100644 (file)
@@ -1,7 +1,7 @@
 # Split bi-quadratic to linear
 
 import salome
-salome.salome_init()
+salome.salome_init_without_session()
 
 from salome.geom import geomBuilder
 geompy = geomBuilder.New()
diff --git a/doc/salome/examples/ssl_hdf5_symbols_conflicts.py b/doc/salome/examples/ssl_hdf5_symbols_conflicts.py
new file mode 100644 (file)
index 0000000..c888638
--- /dev/null
@@ -0,0 +1,21 @@
+#!/usr/bin/env python
+
+"""
+tuleap26358 : Non regression test pointing to an incompatibiliy between hdf5 symbols in CGNS and hdf5 symbols
+in hdf5 library.
+"""
+
+import salome
+salome.standalone()
+salome.salome_init()
+import  SMESH, SALOMEDS
+from salome.smesh import smeshBuilder
+
+smesh = smeshBuilder.New()
+
+inputMED="Mesh_tri.med"
+
+([Mesh_tri_1], status) = smesh.CreateMeshesFromMED(inputMED)
+import SMESH
+if status != SMESH.DRS_OK:
+    raise RuntimeError("Test failed")
index 52fb17c7b5312eef46b8315abec4ba311d9a844e..f26bfd718759063c3b49e08ce3e04ef01bcff588 100644 (file)
@@ -3,7 +3,7 @@
 import sys
 import salome
 
-salome.salome_init()
+salome.salome_init_without_session()
 
 ###
 ### GEOM component
old mode 100755 (executable)
new mode 100644 (file)
index a918da2..37f5dec
@@ -13,7 +13,7 @@ ComputeMeshes = True
 
 import salome
 
-salome.salome_init()
+salome.salome_init_without_session()
 theStudy = salome.myStudy
 #
 import iparameters
old mode 100755 (executable)
new mode 100644 (file)
index 0484092..48f1208
@@ -18,7 +18,7 @@ ComputeMeshes = True
 
 import salome
 
-salome.salome_init()
+salome.salome_init_without_session()
 theStudy = salome.myStudy
 #
 import iparameters
index d674d6471dd49d8d2f83e75cfe3e043734800970..f3ae67d3a2ba18601fc339270958024397eacbad 100644 (file)
@@ -113,6 +113,7 @@ SET(GOOD_TESTS
   filters_ex39.py
   filters_node_nb_conn.py
   filters_belong2group.py
+  find_salome_actor_delegate_to_vtk.py
   grouping_elements_ex01.py
   grouping_elements_ex02.py
   grouping_elements_ex03.py
@@ -198,6 +199,7 @@ set(SESSION_FREE_TESTS
   basic_shaper_smesh_without_session.py
   shaper_smesh_groups_without_session.py
   basic_smesh_output_with_mc_field.py
+  ssl_hdf5_symbols_conflicts.py
 )
 
 SET(EXAMPLES_TESTS ${BAD_TESTS} ${GOOD_TESTS} ${SESSION_FREE_TESTS} testme.py)
index cf0999c5b7c63158ed5ca783e9fcc0ffb2c24f43..edd4cb438aea3e310dfaaebc39fd9868505d9d7d 100644 (file)
@@ -1,7 +1,7 @@
 # Scale
 
 import salome
-salome.salome_init()
+salome.salome_init_without_session()
 import GEOM
 from salome.geom import geomBuilder
 geompy = geomBuilder.New()
index 433ae192878939726ebd9455d36fe8e1c06bbdc1..964449fe3b137cd8b4f7170f8cb36cc7d6ad8803 100644 (file)
@@ -2,7 +2,7 @@
 
 
 import salome
-salome.salome_init()
+salome.salome_init_without_session()
 from salome.geom import geomBuilder
 geompy = geomBuilder.New()
 
index f14c2ca62be8fa4b3aaf7c1d3325d359a303c719..65865aca55a44134744e3e7129befd0611936cae 100644 (file)
@@ -2,7 +2,7 @@
 
 
 import salome
-salome.salome_init()
+salome.salome_init_without_session()
 import GEOM
 from salome.geom import geomBuilder
 geompy = geomBuilder.New()
index b593e0ef1864813baad55f4501b7ce3c6a545d00..542bb5f54b317ce00b606b02911a025b13c70005 100644 (file)
@@ -2,7 +2,7 @@
 
 
 import salome
-salome.salome_init()
+salome.salome_init_without_session()
 import GEOM
 from salome.geom import geomBuilder
 geompy = geomBuilder.New()
index 59403f7db215d44b7748eae8a2359614c8ba62e5..bbc76691ca3af36fc4d7d4083e7ac1f3ecce1a39 100644 (file)
@@ -2,7 +2,7 @@
 
 
 import salome
-salome.salome_init()
+salome.salome_init_without_session()
 import GEOM
 from salome.geom import geomBuilder
 geompy = geomBuilder.New()
index af3d9ff8e69e96f9521bbf12c7bfb1317278e062..f3de43d215d9e7f552710fbd06f889e4e7a894d2 100644 (file)
@@ -1,7 +1,7 @@
 # Sew Side Elements
 
 import salome
-salome.salome_init()
+salome.salome_init_without_session()
 import GEOM
 from salome.geom import geomBuilder
 geompy = geomBuilder.New()
index 2e6a8c6d5f8c795a0177fe0fb9a4e2d1b3760fd9..d4137e41deac96f314e298b80c1a38123c2f5c6f 100644 (file)
@@ -2,7 +2,7 @@
 
 
 import salome
-salome.salome_init()
+salome.salome_init_without_session()
 
 import GEOM
 from salome.geom import geomBuilder
index 072fc3ca1903f124a3f9de36dc80559224221345..65b05d7d51bb69f9c0540df9a54833485c61ae7f 100644 (file)
@@ -2,7 +2,7 @@
 
 
 import salome
-salome.salome_init()
+salome.salome_init_without_session()
 import GEOM
 from salome.geom import geomBuilder
 geompy = geomBuilder.New()
index 12d03892fa8f5fce8012bf9fe7424fdf4a9e4e0b..94b6f7f22d7bc2d7035151a26b925a83bc4f37f1 100644 (file)
@@ -2,7 +2,7 @@
 
 
 import salome
-salome.salome_init()
+salome.salome_init_without_session()
 import GEOM
 from salome.geom import geomBuilder
 geompy = geomBuilder.New()
index 0ef132b66f6d5dbb92da95c9c0ed156314d2b64b..0d41392551b21438dae663b3b48a15575f0ad7c4 100644 (file)
@@ -2,7 +2,7 @@
 
 
 import salome
-salome.salome_init()
+salome.salome_init_without_session()
 import GEOM
 from salome.geom import geomBuilder
 geompy = geomBuilder.New()
index d90d24a3a8f875508bff279b7947f9482d0aa9d2..0e8899eeb7f28ebc7c280016dd7f0934bd41b9fa 100644 (file)
@@ -2,7 +2,7 @@
 
 
 import salome
-salome.salome_init()
+salome.salome_init_without_session()
 import GEOM
 from salome.geom import geomBuilder
 geompy = geomBuilder.New()
index 0dfa09a8557feed77f5746a8bc64d833208ef44b..402e89b97492216c3d7559cfce01634b89747660 100644 (file)
@@ -2,7 +2,7 @@
 
 
 import salome
-salome.salome_init()
+salome.salome_init_without_session()
 import GEOM
 from salome.geom import geomBuilder
 geompy = geomBuilder.New()
index 497adcd95ef8fcfbe252c18659c598f9dbfa0130..100fbe014cf58fcf89000e62cef0cdf81b153a19 100644 (file)
Binary files a/doc/salome/gui/SMESH/images/ctrlinfo.png and b/doc/salome/gui/SMESH/images/ctrlinfo.png differ
index 98e362f388837641fa0a85dbae8fb0897715334c..74176d8897dd78eeffbd3c804096035962a3e33f 100644 (file)
Binary files a/doc/salome/gui/SMESH/images/extrusion_along_path_dlg.png and b/doc/salome/gui/SMESH/images/extrusion_along_path_dlg.png differ
index 761f09bda1e6c4894c3d05039b96a2eeb4da4078..cc97577094dafe91be2617c2e90e6db5dbeb08ed 100644 (file)
Binary files a/doc/salome/gui/SMESH/images/extrusionalongaline1.png and b/doc/salome/gui/SMESH/images/extrusionalongaline1.png differ
index 5f75d5d7405dbc0d721166c01263360b133a1d79..18928d1d0d01a31dd0477d0d59f1e9bf715080af 100644 (file)
Binary files a/doc/salome/gui/SMESH/images/revolution1.png and b/doc/salome/gui/SMESH/images/revolution1.png differ
index d490092d1e833ef2c5b00c32760c4ee402bbd343..27a57c894cc24edb5544fa21a0d1b1b1807641dc 100644 (file)
@@ -33,6 +33,7 @@
 
 #include <Utils_SALOME_Exception.hxx>
 #include <Basics_Utils.hxx>
+#include "SMESH_TypeDefs.hxx"
 
 #ifndef WIN32
 #include <unistd.h> // getpid()
@@ -1403,8 +1404,17 @@ void MgAdapt::convertMedFile(std::string& meshFormatMeshFileName, std::string& s
     checkTimeStepRank(medFileIn) ;
     MEDCoupling::MCAuto<MEDCoupling::MEDFileAnyTypeFieldMultiTS> fts( mfd->getFields()->getFieldWithName(fieldName) );
     MEDCoupling::MCAuto<MEDCoupling::MEDFileAnyTypeField1TS> f = fts->getTimeStep(timeStep, rank);
-    MEDCoupling::MCAuto<MEDCoupling::MEDFileFieldMultiTS> tmFts = MEDCoupling::MEDFileFieldMultiTS::New();
-    tmFts->pushBackTimeStep(f);
+    MEDCoupling::MCAuto<MEDCoupling::MEDFileFieldMultiTS> tmFts = MEDCoupling::DynamicCast<MEDCoupling::MEDFileAnyTypeFieldMultiTS,MEDCoupling::MEDFileFieldMultiTS>(fts);
+
+    // if not able to cast to double field, try float field
+    if (!tmFts)
+    {
+      MEDCoupling::MCAuto<MEDCoupling::MEDFileFloatFieldMultiTS>  tmFtsFloat = MEDCoupling::DynamicCast<MEDCoupling::MEDFileAnyTypeFieldMultiTS,MEDCoupling::MEDFileFloatFieldMultiTS>(fts);
+      if (!tmFtsFloat)
+        THROW_SALOME_EXCEPTION("\nUnexpected field type.\n");
+      // convert float field to double
+      tmFts = tmFtsFloat->convertToDouble();
+    }
 
     fields->pushField(tmFts);
 
index a4714beb732c231a73a095cd69da944bef372e12..ca9c787671c3d60192e31a4a93ef124ecdaf9636 100644 (file)
@@ -659,6 +659,7 @@ namespace
     bool toCreateGroups = resMgr->booleanValue( "SMESH", "auto_groups", false );
     bool   toOverwrite  = true;
     bool   toFindOutDim = true;
+    bool    saveNumbers = resMgr->booleanValue( "SMESH", "med_save_numbers", true );
     bool     toRenumber = true;
     double         zTol = resMgr->doubleValue( "SMESH", "med_ztolerance", 0. );
 
@@ -770,7 +771,9 @@ namespace
           aDefaultFilter = it.key();
       }
       QStringList checkBoxes;
-      checkBoxes << QObject::tr("SMESH_AUTO_GROUPS") << QObject::tr("SMESH_AUTO_DIM");
+      checkBoxes << QObject::tr("SMESH_AUTO_GROUPS")
+                 << QObject::tr("SMESH_AUTO_DIM")
+                 << QObject::tr("SMESH_MED_SAVE_NUMS");
 
       SMESHGUI_FieldSelectorWdg* fieldSelWdg = new SMESHGUI_FieldSelectorWdg();
       QList< QWidget* > wdgList;
@@ -798,6 +801,7 @@ namespace
       fd->selectNameFilter( aDefaultFilter );
       fd->SetChecked( toCreateGroups, 0 );
       fd->SetChecked( toFindOutDim,   1 );
+      fd->SetChecked( saveNumbers,    2 );
       if ( !anInitialPath.isEmpty() )
         fd->setDirectory( anInitialPath );
       fd->selectFile(aMeshName);
@@ -888,6 +892,7 @@ namespace
       }
       toCreateGroups = fd->IsChecked(0);
       toFindOutDim   = fd->IsChecked(1);
+      saveNumbers    = fd->IsChecked(2);
       zTol           = zTolCheck->isChecked() ? zTolSpin->value() : -1;
       fieldSelWdg->GetSelectedFields();
       if ( resMgr ) resMgr->setValue( "SMESH", "enable_ztolerance", zTolCheck->isChecked() );
@@ -927,7 +932,6 @@ namespace
 //         }
         if ( isMED && isOkToWrite )
         {
-          const bool saveNumbers = resMgr->booleanValue( "SMESH", "med_save_numbers", true );
           aMeshIter = aMeshList.begin();
           for( int aMeshIndex = 0; aMeshIter != aMeshList.end(); aMeshIter++, aMeshIndex++ )
           {
index 51627d0ac05d630e395168386ffd59955768f57e..9afbe218c28d6e73798daceb162d9412d3860329 100644 (file)
@@ -264,13 +264,15 @@ SMESHGUI_ExtrusionAlongPathDlg::SMESHGUI_ExtrusionAlongPathDlg( SMESHGUI* theMod
   myPreviewCheckBox = new QCheckBox(tr("PREVIEW"), GroupArguments);
 
   // layouting
-  GroupArgumentsLayout->addWidget(SelectorWdg,          0, 0, 1, 2);
-  GroupArgumentsLayout->addWidget(PathGrp,              1, 0, 1, 2);
-  GroupArgumentsLayout->addWidget(BasePointGrp,         2, 0, 1, 2);
-  GroupArgumentsLayout->addWidget(AnglesGrp,            3, 0);
-  GroupArgumentsLayout->addWidget(ScalesGrp,            3, 1);
-  GroupArgumentsLayout->addWidget(myPreviewCheckBox,    4, 0);
-  GroupArgumentsLayout->addWidget(MakeGroupsCheck,      5, 0);
+  GroupArgumentsLayout->addWidget(SelectorWdg,          0, 0, 3, 2);
+  GroupArgumentsLayout->addWidget(PathGrp,              0, 2, 1, 2);
+  GroupArgumentsLayout->addWidget(BasePointGrp,         1, 2, 1, 2);
+  GroupArgumentsLayout->addWidget(AnglesGrp,            2, 2);
+  GroupArgumentsLayout->addWidget(ScalesGrp,            2, 3);
+  GroupArgumentsLayout->addWidget(myPreviewCheckBox,    3, 0);
+  GroupArgumentsLayout->addWidget(MakeGroupsCheck,      3, 1);
+  SelectorWdg->setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding));
+  SelectorWdg->setMinimumWidth(320);
 
   /***************************************************************/
   // common buttons group box
index 13ce13deb7a0945545653dcecde29d7784509c6b..ce69ade5e63432a1517365400e29c8c4543f903f 100644 (file)
@@ -766,38 +766,53 @@ SMESHGUI_ExtrusionDlg::SMESHGUI_ExtrusionDlg (SMESHGUI* theModule)
   AnglesGrpLayout->setRowMinimumHeight(1, 10);
   AnglesGrpLayout->setRowStretch(3, 10);
 
+  // Controls for advanced parameters
+  QGridLayout* AdvancedGrpLayout = new QGridLayout();
+  AdvancedGrpLayout->setSpacing(SPACING);
+
+  // layouting
+  AdvancedGrpLayout->addWidget(TextLabelDistance,      0, 0);
+  AdvancedGrpLayout->addWidget(TextLabelDx,            0, 2);
+  AdvancedGrpLayout->addWidget(SpinBox_Dx,             0, 3);
+  AdvancedGrpLayout->addWidget(TextLabelDy,            0, 4);
+  AdvancedGrpLayout->addWidget(SpinBox_Dy,             0, 5);
+  AdvancedGrpLayout->addWidget(TextLabelDz,            0, 6);
+  AdvancedGrpLayout->addWidget(SpinBox_Dz,             0, 7);
+  AdvancedGrpLayout->addWidget(TextLabelVector,        1, 0);
+  AdvancedGrpLayout->addWidget(SelectVectorButton,     1, 1);
+  AdvancedGrpLayout->addWidget(TextLabelVx,            1, 2);
+  AdvancedGrpLayout->addWidget(SpinBox_Vx,             1, 3);
+  AdvancedGrpLayout->addWidget(TextLabelVy,            1, 4);
+  AdvancedGrpLayout->addWidget(SpinBox_Vy,             1, 5);
+  AdvancedGrpLayout->addWidget(TextLabelVz,            1, 6);
+  AdvancedGrpLayout->addWidget(SpinBox_Vz,             1, 7);
+  AdvancedGrpLayout->addWidget(TextLabelDist,          2, 0);
+  AdvancedGrpLayout->addWidget(SpinBox_VDist,          2, 3);
+  AdvancedGrpLayout->addWidget(TextLabelNbSteps,       3, 0, 1, 3);
+  AdvancedGrpLayout->addWidget(SpinBox_NbSteps,        3, 3);
+  AdvancedGrpLayout->addWidget(ByAverageNormalCheck,   4, 0, 1, 4);
+  AdvancedGrpLayout->addWidget(UseInputElemsOnlyCheck, 4, 4, 1, 4);
+
+  // Controls for advanced parameters
+  QGroupBox* RbGrp = new QGroupBox();
+  QHBoxLayout* RBLayout = new QHBoxLayout(RbGrp);
+  RBLayout->setSpacing(SPACING); RBLayout->setMargin(MARGIN);
+  RBLayout->addWidget(ExtrMethod_RBut0);
+  RBLayout->addWidget(ExtrMethod_RBut1);
+  RBLayout->addWidget(ExtrMethod_RBut2);
+
   // layouting
-  GroupArgumentsLayout->addWidget(SelectorWdg,            0, 0, 1, 9);
-  GroupArgumentsLayout->addWidget(ExtrMethod_RBut0,       1, 0, 1, 3);
-  GroupArgumentsLayout->addWidget(ExtrMethod_RBut1,       1, 3, 1, 3);
-  GroupArgumentsLayout->addWidget(ExtrMethod_RBut2,       1, 6, 1, 3);
-  GroupArgumentsLayout->addWidget(TextLabelDistance,      2, 0);
-  GroupArgumentsLayout->addWidget(TextLabelDx,            2, 2);
-  GroupArgumentsLayout->addWidget(SpinBox_Dx,             2, 3);
-  GroupArgumentsLayout->addWidget(TextLabelDy,            2, 4);
-  GroupArgumentsLayout->addWidget(SpinBox_Dy,             2, 5);
-  GroupArgumentsLayout->addWidget(TextLabelDz,            2, 6);
-  GroupArgumentsLayout->addWidget(SpinBox_Dz,             2, 7);
-  GroupArgumentsLayout->addWidget(TextLabelVector,        3, 0);
-  GroupArgumentsLayout->addWidget(SelectVectorButton,     3, 1);
-  GroupArgumentsLayout->addWidget(TextLabelVx,            3, 2);
-  GroupArgumentsLayout->addWidget(SpinBox_Vx,             3, 3);
-  GroupArgumentsLayout->addWidget(TextLabelVy,            3, 4);
-  GroupArgumentsLayout->addWidget(SpinBox_Vy,             3, 5);
-  GroupArgumentsLayout->addWidget(TextLabelVz,            3, 6);
-  GroupArgumentsLayout->addWidget(SpinBox_Vz,             3, 7);
-  GroupArgumentsLayout->addWidget(TextLabelDist,          4, 0);
-  GroupArgumentsLayout->addWidget(SpinBox_VDist,          4, 3);
-  GroupArgumentsLayout->addWidget(TextLabelNbSteps,       5, 0, 1, 3);
-  GroupArgumentsLayout->addWidget(SpinBox_NbSteps,        5, 3);
-  GroupArgumentsLayout->addWidget(ByAverageNormalCheck,   6, 0, 1, 4);
-  GroupArgumentsLayout->addWidget(UseInputElemsOnlyCheck, 6, 4, 1, 4);
-  GroupArgumentsLayout->addWidget(BasePointGrp,           7, 0, 1, 9);
-  GroupArgumentsLayout->addWidget(ScalesGrp,              8, 0, 1, 4);
-  GroupArgumentsLayout->addWidget(AnglesGrp,              8, 5, 1, 4);
-  GroupArgumentsLayout->addWidget(myPreviewCheckBox,      9, 0, 1, 8);
-  GroupArgumentsLayout->addWidget(MakeGroupsCheck,        10,0, 1, 8);
-  GroupArgumentsLayout->addItem(new QSpacerItem(0, 0, QSizePolicy::Minimum, QSizePolicy::Expanding), 10, 0);
+  GroupArgumentsLayout->addWidget(RbGrp,                  0, 0, 1, 4);
+  GroupArgumentsLayout->addWidget(SelectorWdg,            1, 0, 3, 2);
+  GroupArgumentsLayout->addLayout(AdvancedGrpLayout,      1, 2, 1, 2);
+  GroupArgumentsLayout->addWidget(BasePointGrp,           2, 2, 1, 2);
+  GroupArgumentsLayout->addWidget(ScalesGrp,              3, 2, 1, 1);
+  GroupArgumentsLayout->addWidget(AnglesGrp,              3, 3, 1, 1);
+  GroupArgumentsLayout->addWidget(myPreviewCheckBox,      4, 0);
+  GroupArgumentsLayout->addWidget(MakeGroupsCheck,        4, 1);
+  GroupArgumentsLayout->setRowStretch(5, 10);
+  SelectorWdg->setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding));
+  SelectorWdg->setMinimumWidth(320);
 
   /***************************************************************/
   GroupButtons = new QGroupBox(this);
index 183d9468bf3ddbc99bd17905ec04d16f0cd7ba27..57fce1eea0c252d7f8f55c4000144c7fe18bcf12 100644 (file)
 
 #include <QString>
 
+#include <TopExp.hxx>
+#include <TopExp_Explorer.hxx>
+#include <TopTools_IndexedMapOfShape.hxx>
+#include <TopoDS_Iterator.hxx>
+
 namespace SMESH
 {
   GEOM::GEOM_Gen_var GetGEOMGen( GEOM::GEOM_Object_ptr go )
@@ -244,4 +249,80 @@ namespace SMESH
   }
 
 
+  //================================================================================
+  /*!
+   * \brief Return type of shape contained in a group
+   */
+  //================================================================================
+
+  TopAbs_ShapeEnum _getGroupType(const TopoDS_Shape& group)
+  {
+    if ( group.ShapeType() != TopAbs_COMPOUND )
+      return group.ShapeType();
+
+    // iterate on a compound
+    TopoDS_Iterator it( group );
+    if ( it.More() )
+      return _getGroupType( it.Value() );
+
+    return TopAbs_SHAPE;
+  }
+
+
+  //================================================================================
+  /*!
+   * \brief Check if a subGeom contains sub-shapes of a mainGeom
+   */
+  //================================================================================
+
+  bool ContainsSubShape( GEOM::GEOM_Object_ptr mainGeom,
+                         GEOM::GEOM_Object_ptr subGeom )
+  {
+    if ( CORBA::is_nil( mainGeom ) ||
+         CORBA::is_nil( subGeom ))
+      return false;
+
+    GEOM::GEOM_Gen_var geomGen = mainGeom->GetGen();
+    if ( geomGen->_is_nil() ) return false;
+
+    GEOM::GEOM_IGroupOperations_wrap op = geomGen->GetIGroupOperations();
+    if ( op->_is_nil() ) return false;
+
+    GEOM::GEOM_Object_var mainObj = op->GetMainShape( subGeom ); /* _var not _wrap as
+                                                                    mainObj already exists! */
+    while ( !mainObj->_is_nil() )
+    {
+      CORBA::String_var entry1 = mainObj->GetEntry();
+      CORBA::String_var entry2 = mainGeom->GetEntry();
+      if ( std::string( entry1.in() ) == entry2.in() )
+        return true;
+      mainObj = op->GetMainShape( mainObj );
+    }
+    if ( subGeom->GetShapeType() == GEOM::COMPOUND )
+    {
+      // is subGeom a compound of sub-shapes?
+      GEOM::GEOM_IShapesOperations_wrap sop = geomGen->GetIShapesOperations();
+      if ( sop->_is_nil() ) return false;
+      GEOM::ListOfLong_var ids = sop->GetAllSubShapesIDs( subGeom,
+                                                          GEOM::SHAPE,/*sorted=*/false);
+      if ( ids->length() > 0 )
+      {
+        GEOM_Client geomClient;
+        TopoDS_Shape  subShape = geomClient.GetShape( geomGen, subGeom );
+        TopoDS_Shape mainShape = geomClient.GetShape( geomGen, mainGeom );
+        if ( subShape.IsNull() || mainShape.IsNull() )
+          return false;
+
+        TopAbs_ShapeEnum subType = _getGroupType( subShape );
+        TopTools_IndexedMapOfShape subMap;
+        TopExp::MapShapes( subShape, subType, subMap );
+        for ( TopExp_Explorer exp( mainShape, subType ); exp.More(); exp.Next() )
+          if ( subMap.Contains( exp.Current() ))
+            return true;
+
+      }
+    }
+    return false;
+  }
+
 } // end of namespace SMESH
index 438e518469670474945ecc55fc7e4bbd71f148dc..04e8bfd93a8525b0a16b6849bf3e325ee31dbd04 100644 (file)
@@ -59,6 +59,9 @@ namespace SMESH
 
   SMESHGUI_EXPORT bool GetGeomEntries( Handle(SALOME_InteractiveObject)& hypIO,
                                        QString& subGeom, QString& meshGeom);
+
+  SMESHGUI_EXPORT bool ContainsSubShape( GEOM::GEOM_Object_ptr mainShape,
+                                         GEOM::GEOM_Object_ptr subShape );
 }
 
 #endif // SMESHGUI_GEOMGENUTILS_H
index a231ff18a9b7205a754751c10ab99b583876c255..18f2612341e973f17be2a6a2854671a7fe1ca67d 100644 (file)
@@ -1405,72 +1405,23 @@ void SMESHGUI_GroupDlg::onObjectSelectionChanged()
     else if (myCurrentLineEdit == myGeomGroupLine)
     {
       myGeomObjects = new GEOM::ListOfGO();
+      myGeomObjects->length( aNbSel );
 
-      // The mesh SObject
-      _PTR(SObject) aMeshSO = SMESH::FindSObject(myMesh);
-
-      if (aNbSel == 0 || !aMeshSO)
+      if ( aNbSel == 0 || myMesh->_is_nil() )
       {
-        myGeomObjects->length(0);
         updateButtons();
         myIsBusy = false;
         return;
       }
 
-      myGeomObjects->length(aNbSel);
-
-      GEOM::GEOM_Object_var aGeomGroup;
+      GEOM::GEOM_Object_var mainGeom = myMesh->GetShapeToMesh();
       int i = 0;
-
-      SALOME_ListIteratorOfListIO anIt (aList);
-      for (; anIt.More(); anIt.Next())
+      for ( SALOME_ListIteratorOfListIO anIt( aList ); anIt.More(); anIt.Next() )
       {
-        CORBA::Object_var aGroupObj = SMESH::IObjectToObject(anIt.Value());
-        if (CORBA::is_nil(aGroupObj))
-          continue;
-        // Check if the object is a geometry group
-        aGeomGroup = GEOM::GEOM_Object::_narrow(aGroupObj);
-        if (CORBA::is_nil(aGeomGroup))
-          continue;
-
         // Check if group constructed on the same shape as a mesh or on its child
-
-        // The main shape of the group
-        GEOM::GEOM_Object_var aGroupMainShape;
-        if (aGeomGroup->GetType() == 37)
-        {
-          GEOM::GEOM_IGroupOperations_wrap anOp =
-            SMESH::GetGEOMGen( aGeomGroup )->GetIGroupOperations();
-          aGroupMainShape = anOp->GetMainShape( aGeomGroup );
-          // aGroupMainShape is an existing servant => GEOM_Object_var not GEOM_Object_wrap
-        }
-        else
-        {
-          aGroupMainShape = aGeomGroup;
-          aGroupMainShape->Register();
-        }
-        CORBA::String_var entry = aGroupMainShape->GetStudyEntry();
-        _PTR(SObject) aGroupMainShapeSO =
-          SMESH::getStudy()->FindObjectID( entry.in() );
-
-        _PTR(SObject) anObj, aRef;
-        bool isRefOrSubShape = false;
-        if (aMeshSO->FindSubObject(1, anObj) &&  anObj->ReferencedObject(aRef)) {
-          if (aRef->GetID() == aGroupMainShapeSO->GetID()) {
-            isRefOrSubShape = true;
-          } else {
-            _PTR(SObject) aFather = aGroupMainShapeSO->GetFather();
-            _PTR(SComponent) aComponent = aGroupMainShapeSO->GetFatherComponent();
-            while (!isRefOrSubShape && aFather->GetID() != aComponent->GetID()) {
-              if (aRef->GetID() == aFather->GetID())
-                isRefOrSubShape = true;
-              else
-                aFather = aFather->GetFather();
-            }
-          }
-        }
-        if (isRefOrSubShape)
-          myGeomObjects[i++] = aGeomGroup;
+        GEOM::GEOM_Object_var geomGroup = SMESH::GetGeom( anIt.Value() );
+        if ( SMESH::ContainsSubShape( mainGeom, geomGroup ))
+          myGeomObjects[ i++ ] = geomGroup;
       }
 
       myGeomObjects->length(i);
index 9344c62b4d7c985c7e4be4bd437ca0f98cf9f593..606a0a7325a155245a70a467c90628ac06f00392 100644 (file)
@@ -178,7 +178,7 @@ private:
   QPushButton*                  myAddBtn;
   QPushButton*                  myRemoveBtn;
   QPushButton*                  mySortBtn;
-  
+
   QGroupBox*                    mySelectBox;
   QCheckBox*                    mySelectSubMesh;
   QPushButton*                  mySubMeshBtn;
@@ -186,9 +186,9 @@ private:
   QCheckBox*                    mySelectGroup;
   QPushButton*                  myGroupBtn;
   QLineEdit*                    myGroupLine;
-  
+
   QtxColorButton*               myColorBtn;
-  
+
   QCheckBox*                    mySelectGeomGroup;
   QToolButton*                  myGeomGroupBtn;
   QLineEdit*                    myGeomGroupLine;
@@ -198,9 +198,9 @@ private:
   QPushButton*                  myApplyBtn;
   QPushButton*                  myCloseBtn;
   QPushButton*                  myHelpBtn;
-  
+
   SMESHGUI_ShapeByMeshOp*       myShapeByMeshOp;
-  
+
   SMESH::SMESH_Mesh_var         myMesh;
   QList<SMESH_Actor*>           myActorsList;
   SMESH::SMESH_Group_var        myGroup;
@@ -209,22 +209,19 @@ private:
   SMESH::Filter_var             myFilter;
   QList<int>                    myIdList;
   GEOM::ListOfGO_var            myGeomObjects;
-  
+
   int                           mySelectionMode;
-  //Handle(SMESH_TypeFilter)      myMeshFilter;
-  //Handle(SMESH_TypeFilter)      mySubMeshFilter;
-  //Handle(SMESH_TypeFilter)      myGroupFilter;
   SUIT_SelectionFilter*         myMeshFilter;
   SMESH_LogicalFilter*          mySubMeshFilter;
   SMESH_LogicalFilter*          myGroupFilter;
   SUIT_SelectionFilter*         myGeomFilter;
-  
+
   SMESHGUI_FilterDlg*           myFilterDlg;
-  
+
   bool                          myCreate, myIsBusy;
-  
+
   QString                       myHelpFileName;
-  
+
   QMap<QAction*, int>           myActions;
 
   bool                          myNameChanged; //added by skl for IPAL19574
index b0137dd1ff0c0111c1f61d07865a05a2ff5a7c26..f7dccaff45c6304e29d3f6a81d9533a6d885f68c 100644 (file)
@@ -463,29 +463,23 @@ void SMESHGUI_GroupOnShapeOp::selectionDone()
     // study
     if (_PTR(Study) aStudy = SMESH::getStudy()) {
       // mesh
-      if (_PTR(SObject)  meshSO = aStudy->FindObjectID( myMeshID.toUtf8().data() )) {
+      if (_PTR(SObject) meshSO = aStudy->FindObjectID( myMeshID.toUtf8().data() ))
+      {
         // shape to mesh
-        _PTR(SObject) anObj, shapeToMesh;
-        if (meshSO->FindSubObject(1, anObj) && anObj->ReferencedObject(shapeToMesh)) {
-          // loop on selected
-          QStringList::iterator name = names.begin(), id = ids.begin(), idEnd = ids.end();
-          for (; id != idEnd; ++id, ++name ) {
-            // shape SO
-            if (_PTR(SObject) shapeSO = aStudy->FindObjectID( id->toUtf8().data() )) {
-            // check if shape SO is a child of shape to mesh 
-              while ( shapeSO && shapeSO->GetID() != shapeToMesh->GetID() )
-                if  ( shapeSO->Depth() < 2 )
-                  shapeSO.reset();
-                else
-                  shapeSO = shapeSO->GetFather();
-              if ( shapeSO ) {
-                //printf( "selectionDone() %s %s\n", (*id).latin1(), (*name).latin1() );
-                if ( !goodIds.contains( *id )) {
-                  goodIds.append( *id );
-                  goodNames.append( *name );
-                }
-              }
-            }
+        GEOM::GEOM_Object_var mainGeom = SMESH::GetGeom( meshSO );
+        // loop on selected
+        QStringList::iterator name = names.begin(), id = ids.begin(), idEnd = ids.end();
+        for (; id != idEnd; ++id, ++name )
+        {
+          if ( goodIds.contains( *id ))
+            continue;
+          // shape SO
+          _PTR(SObject) shapeSO = aStudy->FindObjectID( id->toUtf8().data() );
+          GEOM::GEOM_Object_var subGeom = SMESH::GetGeom( shapeSO );
+          if ( SMESH::ContainsSubShape( mainGeom, subGeom ))
+          {
+            goodIds.append( *id );
+            goodNames.append( *name );
           }
         }
       }
index 20f2a7ee657471469361163b65c9984fe344b8d9..157cbdf835eab9cf33b40a3a96826ba73223181e 100644 (file)
@@ -58,27 +58,15 @@ protected:
   virtual void                  startOperation();
   virtual void                  selectionDone();
   virtual SUIT_SelectionFilter* createFilter( const int ) const;
-  //virtual bool                  isValid( SUIT_Operation* ) const;
 
 private slots:
 
     bool                        onApply();
     void                        onButtonClick();
 
-
-//     void                        onSelectColor();
-
-
 private:
 
     void                        init();
-//     void                        setGroupColor( const SALOMEDS::Color& );
-//     SALOMEDS::Color             getGroupColor() const;
-
-//     void                        setGroupQColor( const QColor& );
-//     QColor                      getGroupQColor() const;
-
-//     void                        setDefaultGroupColor();
 
 private:
 
@@ -86,7 +74,6 @@ private:
 
   QString                       myMeshID;
   QStringList                   myElemGeoIDs, myNodeGeoIDs;
-  //GEOM::ListOfGO_var            myElemGObj;
 };
 
 class SMESHGUI_EXPORT SMESHGUI_GroupOnShapeDlg : public SMESHGUI_Dialog
@@ -104,22 +91,14 @@ public slots:
 
 private:
 
-  //QLineEdit*                    myGrpNameLine;
-
   QPushButton*                  myMeshBtn;
   QLineEdit*                    myMeshLine;
 
   QPushButton*                  myElemGeomBtn;
-  QListWidget*                     myElemGeomList;
+  QListWidget*                  myElemGeomList;
 
   QPushButton*                  myNodeGeomBtn;
-  QListWidget*                     myNodeGeomList;
-
-//   QPushButton*                  myColorBtn;
-
-//   bool                          myCreate, myIsBusy;
-
-//   QString                       myHelpFileName;
+  QListWidget*                  myNodeGeomList;
 
   friend class SMESHGUI_GroupOnShapeOp;
 };
index a6d6b3cda6c1a89cb0076b45c8037432030a6928..37ed558db44faee35f6497fa3ee1398385b9dc3f 100644 (file)
@@ -3432,6 +3432,9 @@ SMESHGUI_CtrlInfo::SMESHGUI_CtrlInfo( QWidget* parent ): SMESHGUI_Info( parent )
   QIcon aComputeIcon( SUIT_Session::session()->resourceMgr()->loadPixmap( "SMESH", tr( "ICON_COMPUTE" ) ) );
   SMESH::FilterManager_var aFilterMgr = SMESH::GetFilterManager();
 
+  // QToolBox with MeshInfo
+  myMeshTB = new QToolBox(this);
+
   // name
   QLabel* aNameLab = createLabel( tr( "NAME_LAB" ), this, Bold );
   QLabel* aName = createField( this, "ctrlName" );
@@ -3547,50 +3550,82 @@ SMESHGUI_CtrlInfo::SMESHGUI_CtrlInfo( QWidget* parent ): SMESHGUI_Info( parent )
   connect( aOverContVolumesBtn,SIGNAL( clicked() ), this, SLOT( computeOverConstrainedVolumesInfo() ) );
   connect( myToleranceWidget, SIGNAL( valueChanged( double ) ), this, SLOT( setTolerance( double ) ) );
 
-  l->addWidget( aNameLab,           0, 0 );       //0
-  l->addWidget( aName,              0, 1, 1, 2 ); //1
-  l->addWidget( aNodesLab,          1, 0, 1, 3 ); //2
-  l->addWidget( aNodesFreeLab,      2, 0 );       //3
-  l->addWidget( aNodesFree,         2, 1 );       //4
-  l->addWidget( aFreeNodesBtn,      2, 2 );       //5
-  l->addWidget( aNodesNbConnLab,    3, 0 );       //6
-  l->addWidget( aNodesNbConn,       3, 1 );       //7
-  l->addWidget( aNodesNbConnBtn,    3, 2 );       //8
-  l->addWidget( aNodesDoubleLab,    4, 0 );       //9
-  l->addWidget( aNodesDouble,       4, 1 );       //10
-  l->addWidget( aDoubleNodesBtn,    4, 2 );       //11
-  l->addWidget( aToleranceLab,      5, 0 );       //12
-  l->addWidget( myToleranceWidget,  5, 1 );       //13
-  l->addWidget( anEdgesLab,         6, 0, 1, 3 ); //14
-  l->addWidget( anEdgesDoubleLab,   7, 0 );       //15
-  l->addWidget( anEdgesDouble,      7, 1 );       //16
-  l->addWidget( aDoubleEdgesBtn,    7, 2 );       //17
-  l->addWidget( aFacesLab,          8, 0, 1, 3 ); //18
-  l->addWidget( aFacesDoubleLab,    9, 0 );       //19
-  l->addWidget( aFacesDouble,       9, 1 );       //20
-  l->addWidget( aDoubleFacesBtn,    9, 2 );       //21
-  l->addWidget( aFacesOverLab,      10, 0 );      //22
-  l->addWidget( aFacesOver,         10, 1 );      //23
-  l->addWidget( aOverContFacesBtn,  10, 2 );      //24
-  l->addWidget( anAspectRatioLab,   11, 0 );      //25
-  l->addWidget( aComputeFaceBtn,    11, 2 );      //26
-  l->addWidget( myPlot,             12, 0, 1, 3 );//27
-  l->addWidget( aVolumesLab,        13, 0, 1, 3 );//28
-  l->addWidget( aVolumesDoubleLab,  14, 0 );      //29
-  l->addWidget( aVolumesDouble,     14, 1 );      //30
-  l->addWidget( aDoubleVolumesBtn,  14, 2 );      //31
-  l->addWidget( aVolumesOverLab,    15, 0 );      //32
-  l->addWidget( aVolumesOver,       15, 1 );      //33
-  l->addWidget( aOverContVolumesBtn,15, 2 );      //34
-  l->addWidget( anAspectRatio3DLab, 16, 0 );      //35
-  l->addWidget( aComputeVolumeBtn,  16, 2 );      //36
-  l->addWidget( myPlot3D,           17, 0, 1, 3 );//37
-  l->setColumnStretch(  0,  0 );
-  l->setColumnStretch(  1,  5 );
-  l->setRowStretch   ( 12,  5 );
-  l->setRowStretch   ( 17,  5 );
-  l->setRowStretch   ( 18,  1 );
+  l->addWidget( aNameLab,           0, 0 ); //0
+  l->addWidget( aName,              0, 1 ); //1
+  
+  // Node group
+  QWidget* NodeGrp = new QWidget();
+  QGridLayout* NodeLayout = new QGridLayout(NodeGrp);
+  NodeLayout->setSpacing(SPACING); NodeLayout->setMargin(MARGIN);
+
+  NodeLayout->addWidget( aNodesFreeLab,      0, 0 );
+  NodeLayout->addWidget( aNodesFree,         0, 1 );
+  NodeLayout->addWidget( aFreeNodesBtn,      0, 2 );
+  NodeLayout->addWidget( aNodesNbConnLab,    1, 0 );
+  NodeLayout->addWidget( aNodesNbConn,       1, 1 );
+  NodeLayout->addWidget( aNodesNbConnBtn,    1, 2 );
+  NodeLayout->addWidget( aNodesDoubleLab,    2, 0 );
+  NodeLayout->addWidget( aNodesDouble,       2, 1 );
+  NodeLayout->addWidget( aDoubleNodesBtn,    2, 2 );
+  NodeLayout->addWidget( aToleranceLab,      3, 0 );
+  NodeLayout->addWidget( myToleranceWidget,  3, 1 );
+  NodeLayout->addWidget( myToleranceWidget,  3, 1 );
+  NodeLayout->setRowStretch(4, 5);
+
+  myMeshTB->addItem(NodeGrp, aNodesLab->text());
+  aNodesLab->setVisible(false);
+
+  // Edge group
+  QWidget* EdgeGrp = new QWidget();
+  QGridLayout* EdgeLayout = new QGridLayout(EdgeGrp);
+  EdgeLayout->setSpacing(SPACING); EdgeLayout->setMargin(MARGIN);
+
+  EdgeLayout->addWidget( anEdgesDoubleLab,   0, 0 );
+  EdgeLayout->addWidget( anEdgesDouble,      0, 1 );
+  EdgeLayout->addWidget( aDoubleEdgesBtn,    0, 2 );
+  EdgeLayout->setRowStretch(1, 5);
+
+  myMeshTB->addItem(EdgeGrp, anEdgesLab->text());
+  anEdgesLab->setVisible(false);
+
+  // Face group
+  QWidget* FaceGrp = new QWidget();
+  QGridLayout* FaceLayout = new QGridLayout(FaceGrp);
+  FaceLayout->setSpacing(SPACING); FaceLayout->setMargin(MARGIN);
+
+  FaceLayout->addWidget( aFacesDoubleLab,    0, 0 );
+  FaceLayout->addWidget( aFacesDouble,       0, 1 );
+  FaceLayout->addWidget( aDoubleFacesBtn,    0, 2 );
+  FaceLayout->addWidget( aFacesOverLab,      1, 0 );
+  FaceLayout->addWidget( aFacesOver,         1, 1 );
+  FaceLayout->addWidget( aOverContFacesBtn,  1, 2 );
+  FaceLayout->addWidget( anAspectRatioLab,   2, 0 );
+  FaceLayout->addWidget( aComputeFaceBtn,    2, 2 );
+  FaceLayout->addWidget( myPlot,             3, 0, 1, 3 );
+
+  myMeshTB->addItem(FaceGrp, aFacesLab->text());
+  aFacesLab->setVisible(false);
+
+  // Volume group
+  QWidget* VolumeGrp = new QWidget();
+  QGridLayout* VolumeLayout = new QGridLayout(VolumeGrp);
+  VolumeLayout->setSpacing(SPACING); VolumeLayout->setMargin(MARGIN);
+
+  VolumeLayout->addWidget( aVolumesDoubleLab,  0, 0 );
+  VolumeLayout->addWidget( aVolumesDouble,     0, 1 );
+  VolumeLayout->addWidget( aDoubleVolumesBtn,  0, 2 );
+  VolumeLayout->addWidget( aVolumesOverLab,    1, 0 );
+  VolumeLayout->addWidget( aVolumesOver,       1, 1 );
+  VolumeLayout->addWidget( aOverContVolumesBtn,1, 2 );
+  VolumeLayout->addWidget( anAspectRatio3DLab, 2, 0 );
+  VolumeLayout->addWidget( aComputeVolumeBtn,  2, 2 );
+  VolumeLayout->addWidget( myPlot3D,           3, 0, 1, 3 );
+
+  myMeshTB->addItem(VolumeGrp, aVolumesLab->text());
+  aVolumesLab->setVisible(false);
+
+  l->addWidget( myMeshTB,                1, 0, 1, 2 ); //2
+  l->setRowStretch( 2,  5 );
 
   clearInternal();
 }
@@ -3673,8 +3708,8 @@ void SMESHGUI_CtrlInfo::showInfo( const SMESH::SelectionProxy& proxy )
     }
   }
   else {
-    for( int i=2; i<=13; i++)
-      dynamic_cast<QGridLayout*>(layout())->itemAt(i)->widget()->setVisible( false );
+    myMeshTB->setItemEnabled(0, false );
+    myMeshTB->widget(0)->setVisible( false );
   }
 
   // edges info
@@ -3686,8 +3721,8 @@ void SMESHGUI_CtrlInfo::showInfo( const SMESH::SelectionProxy& proxy )
       myButtons[3]->setEnabled( true );
   }
   else {
-    for( int i=14; i<=17; i++)
-      dynamic_cast<QGridLayout*>(layout())->itemAt(i)->widget()->setVisible( false );
+    myMeshTB->setItemEnabled(1, false );
+    myMeshTB->widget(1)->setVisible( false );
   }
 
   // faces info
@@ -3705,14 +3740,10 @@ void SMESHGUI_CtrlInfo::showInfo( const SMESH::SelectionProxy& proxy )
       myButtons[5]->setEnabled( true );
       myButtons[6]->setEnabled( true );
     }
-#ifdef DISABLE_PLOT2DVIEWER
-    for( int i=25; i<=27; i++)
-      dynamic_cast<QGridLayout*>(layout())->itemAt(i)->widget()->setVisible( false );
-#endif
   }
   else {
-    for( int i=18; i<=27; i++)
-      dynamic_cast<QGridLayout*>(layout())->itemAt(i)->widget()->setVisible( false );
+    myMeshTB->setItemEnabled(2, false );
+    myMeshTB->widget(2)->setVisible( false );
   }
 
   // volumes info
@@ -3730,15 +3761,15 @@ void SMESHGUI_CtrlInfo::showInfo( const SMESH::SelectionProxy& proxy )
       myButtons[8]->setEnabled( true );
       myButtons[9]->setEnabled( true );
     }
-#ifdef DISABLE_PLOT2DVIEWER
-    for( int i=35; i<=37; i++)
-      dynamic_cast<QGridLayout*>(layout())->itemAt(i)->widget()->setVisible( false );
-#endif
   }
   else {
-    for( int i=28; i<=37; i++)
-      dynamic_cast<QGridLayout*>(layout())->itemAt(i)->widget()->setVisible( false );
+    myMeshTB->setItemEnabled(3, false );
+    myMeshTB->widget(3)->setVisible( false );
   }
+  myMeshTB->setCurrentIndex(0);
+  myMeshTB->setVisible( (nbNodes + nbElemsByType[ SMESH::EDGE ] + 
+                                   nbElemsByType[ SMESH::FACE ] + 
+                                   nbElemsByType[ SMESH::VOLUME ]) > 0 );
 }
 
 //================================================================================
@@ -3892,8 +3923,10 @@ void SMESHGUI_CtrlInfo::computeAspectRatio3D()
 */
 void SMESHGUI_CtrlInfo::clearInternal()
 {
-  for( int i=0; i<=37; i++)
-    dynamic_cast<QGridLayout*>(layout())->itemAt(i)->widget()->setVisible( true );
+  for (int i=0; i<=3;i++) {
+    myMeshTB->setItemEnabled(i, true );
+    myMeshTB->widget(i)->setVisible( true );
+  }
   for( int i=0; i<=9; i++)
     myButtons[i]->setEnabled( false );
   myPlot->detachItems();
index 82e3adc6c7c574f998b460913d9b1a05ec860fa5..84700d488a1c9069be94cb11782cfd70e43c78fd 100644 (file)
@@ -36,6 +36,7 @@
 #include <QList>
 #include <QMap>
 #include <QSet>
+#include <QToolBox>
 
 #include <SALOMEconfig.h>
 #include CORBA_SERVER_HEADER(SMESH_Filter)
@@ -345,6 +346,7 @@ private:
   ObjectType myObjectType;
   SMESHGUI_SpinBox* myToleranceWidget;
   QList<QLabel*> myWidgets;
+  QToolBox* myMeshTB;
   QwtPlot* myPlot;
   QwtPlot* myPlot3D;
   QList<QAbstractButton*> myButtons;
index 68791630a070bacdbb64d2f1fe3a7a8ea4f50350..e0c88fa1788b406a782cd7b5257525d3fa359545 100644 (file)
@@ -319,25 +319,6 @@ SUIT_SelectionFilter* SMESHGUI_MeshOp::createFilter( const int theId ) const
     return 0;
 }
 
-//================================================================================
-/*!
- * \brief Return type of shape contained in a group
- */
-//================================================================================
-
-TopAbs_ShapeEnum getGroupType(const TopoDS_Shape& group)
-{
-  if ( group.ShapeType() != TopAbs_COMPOUND )
-    return group.ShapeType();
-
-  // iterate on a compound
-  TopoDS_Iterator it( group );
-  if ( it.More() )
-    return getGroupType( it.Value() );
-
-  return TopAbs_SHAPE;
-}
-
 //================================================================================
 /*!
  * \brief check if selected shape is a sub-shape of the shape to mesh
@@ -365,60 +346,17 @@ bool SMESHGUI_MeshOp::isSubshapeOk() const
   QStringList aGEOMs;
   myDlg->selectedObject(SMESHGUI_MeshDlg::Geom, aGEOMs);
 
-  if (aGEOMs.count() > 0) {
-    GEOM::GEOM_Gen_var geomGen = mainGeom->GetGen();
-    if (geomGen->_is_nil()) return false;
+  // check all selected shapes
+  for ( QString& aSubGeomEntry : aGEOMs )
+  {
+    _PTR(SObject) pSubGeom = SMESH::getStudy()->FindObjectID( aSubGeomEntry.toUtf8().data() );
+    if ( !pSubGeom ) return false;
 
-    GEOM::GEOM_IGroupOperations_wrap op = geomGen->GetIGroupOperations();
-    if (op->_is_nil()) return false;
+    GEOM::GEOM_Object_var subGeom =
+      GEOM::GEOM_Object::_narrow(_CAST(SObject,pSubGeom)->GetObject());
 
-    // check all selected shapes
-    QStringList::const_iterator aSubShapesIter = aGEOMs.begin();
-    for ( ; aSubShapesIter != aGEOMs.end(); aSubShapesIter++)
-    {
-      QString aSubGeomEntry = (*aSubShapesIter);
-      _PTR(SObject) pSubGeom = SMESH::getStudy()->FindObjectID(aSubGeomEntry.toUtf8().data());
-      if (!pSubGeom) return false;
-
-      GEOM::GEOM_Object_var aSubGeomVar =
-        GEOM::GEOM_Object::_narrow(_CAST(SObject,pSubGeom)->GetObject());
-      if (aSubGeomVar->_is_nil()) return false;
-
-      // skl for NPAL14695 - implementation of searching of mainObj
-      GEOM::GEOM_Object_var mainObj = op->GetMainShape(aSubGeomVar); /* _var not _wrap as
-                                                                        mainObj already exists! */
-      while( !mainObj->_is_nil())
-      {
-        CORBA::String_var entry1 = mainObj->GetEntry();
-        CORBA::String_var entry2 = mainGeom->GetEntry();
-        if (std::string( entry1.in() ) == entry2.in() )
-          return true;
-        mainObj = op->GetMainShape(mainObj);
-      }
-      if ( aSubGeomVar->GetShapeType() == GEOM::COMPOUND )
-      {
-        // is aSubGeomVar a compound of sub-shapes?
-        GEOM::GEOM_IShapesOperations_wrap sop = geomGen->GetIShapesOperations();
-        if (sop->_is_nil()) return false;
-        GEOM::ListOfLong_var ids = sop->GetAllSubShapesIDs( aSubGeomVar,
-                                                            GEOM::SHAPE,/*sorted=*/false);
-        if ( ids->length() > 0 )
-        {
-          GEOM_Client geomClient;
-          TopoDS_Shape  subShape = geomClient.GetShape( geomGen, aSubGeomVar );
-          TopoDS_Shape mainShape = geomClient.GetShape( geomGen, mainGeom );
-          if ( subShape.IsNull() || mainShape.IsNull() )
-            return false;
-
-          TopAbs_ShapeEnum subType = getGroupType( subShape );
-          TopTools_IndexedMapOfShape subMap;
-          TopExp::MapShapes( subShape, subType, subMap );
-          for ( TopExp_Explorer exp( mainShape, subType ); exp.More(); exp.Next() )
-            if ( subMap.Contains( exp.Current() ))
-              return true;
-        }
-      }
-    }
+    if ( SMESH::ContainsSubShape( mainGeom, subGeom ))
+      return true;
   }
 
   return false;
index 717d747c16f8904e291af6bc114161140d0b02f8..768303fea2b408c5d76824b484e1d65bf7075f9e 100644 (file)
@@ -202,13 +202,15 @@ SMESHGUI_RevolutionDlg::SMESHGUI_RevolutionDlg( SMESHGUI* theModule )
   MakeGroupsCheck = new QCheckBox(tr("SMESH_MAKE_GROUPS"), GroupArguments);
   MakeGroupsCheck->setChecked(true);
 
-  GroupArgumentsLayout->addWidget(SelectorWdg,          0, 0, 1, 4);
-  GroupArgumentsLayout->addWidget(GroupAxis,            1, 0, 1, 4);
-  GroupArgumentsLayout->addWidget(GroupAngleBox,        2, 0, 1, 4);
-  GroupArgumentsLayout->addWidget(TextLabelTolerance,   3, 0, 1, 2);
-  GroupArgumentsLayout->addWidget(SpinBox_Tolerance,    3, 2, 1, 2);
-  GroupArgumentsLayout->addWidget(myPreviewCheckBox,    4, 0, 1, 4);
-  GroupArgumentsLayout->addWidget(MakeGroupsCheck,      5, 0, 1, 4);
+  GroupArgumentsLayout->addWidget(SelectorWdg,          0, 0, 3, 4);
+  GroupArgumentsLayout->addWidget(GroupAxis,            0, 4, 1, 4);
+  GroupArgumentsLayout->addWidget(GroupAngleBox,        1, 4, 1, 4);
+  GroupArgumentsLayout->addWidget(TextLabelTolerance,   2, 4, 1, 2);
+  GroupArgumentsLayout->addWidget(SpinBox_Tolerance,    2, 6, 1, 2);
+  GroupArgumentsLayout->addWidget(myPreviewCheckBox,    3, 0, 1, 2);
+  GroupArgumentsLayout->addWidget(MakeGroupsCheck,      3, 2, 1, 2);
+  SelectorWdg->setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding));
+  SelectorWdg->setMinimumWidth(320);
 
   SelectorWdg->GetButtonGroup()->addButton( SelectVectorButton );
   SelectorWdg->GetButtonGroup()->addButton( SelectPointButton );
index a4b6cfd7ae8c2c8152aa26873157bcf61ac868cb..9c982d71ee1c68612d291e5fbf3bed00f2c4650d 100644 (file)
@@ -1614,6 +1614,10 @@ Please enter correct values and try again</translation>
         <source>SMESH_AUTO_DIM</source>
         <translation>Automatically define space dimension</translation>
     </message>
+    <message>
+        <source>SMESH_MED_SAVE_NUMS</source>
+        <translation>Export indices</translation>
+    </message>
     <message>
         <source>SMESH_ZTOLERANCE</source>
         <translation>Z tolerance</translation>
index cbcc33eb3260f3bc514f2a29671c8b7ea2743f8e..2b4e33cc2971788d2f10b09fe97c865a9eef657e 100644 (file)
@@ -33,7 +33,15 @@ SMESH_Gen_No_Session_i::SMESH_Gen_No_Session_i( CORBA::ORB_ptr orb,
 
 GEOM::GEOM_Gen_var SMESH_Gen_No_Session_i::GetGeomEngine( bool isShaper )
 {
-  CORBA::Object_var temp = KERNEL::RetrieveCompo(isShaper ? "SHAPERSTUDY" : "GEOM");
+  CORBA::Object_var temp;
+  try
+  {
+    temp = KERNEL::RetrieveCompo(isShaper ? "SHAPERSTUDY" : "GEOM");
+  }
+  catch(...)
+  {
+    return GEOM::GEOM_Gen::_nil();
+  }
   myGeomGen = GEOM::GEOM_Gen::_narrow( temp );
   return myGeomGen;
 }
index b34058a2c5d21cd6078e0cee64fbd25730eac5da..336c341ee501fb83fb0e93880972e95b5f8ec56e 100644 (file)
@@ -5916,7 +5916,8 @@ bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent,
               if ( aNewGroup->_is_nil() )
                 continue;
 
-              string iorSubString = GetORB()->object_to_string( aNewGroup );
+              CORBA::String_var iorSubStringVar = GetORB()->object_to_string( aNewGroup );
+              string iorSubString(iorSubStringVar.in());
               int        newSubId = myStudyContext->findId( iorSubString );
               myStudyContext->mapOldToNew( subid, newSubId );
 
@@ -6239,8 +6240,9 @@ int SMESH_Gen_i::RegisterObject(CORBA::Object_ptr theObject)
 CORBA::Long  SMESH_Gen_i::GetObjectId(CORBA::Object_ptr theObject)
 {
   if ( myStudyContext && !CORBA::is_nil( theObject )) {
-    string iorString = GetORB()->object_to_string( theObject );
-    return myStudyContext->findId( iorString );
+    CORBA::String_var iorString = GetORB()->object_to_string( theObject );
+    string iorStringCpp(iorString.in()); 
+    return myStudyContext->findId( iorStringCpp );
   }
   return 0;
 }
index d31ccf2d8db6ecaf681d5edde0db8696f35de486..e4e3f5e8595156f0a0439f9ba70e497731fc8300 100644 (file)
@@ -535,7 +535,7 @@ SALOMEDS::SObject_ptr SMESH_Gen_i::PublishInStudy(SALOMEDS::SObject_ptr /*theSOb
 
 //=======================================================================
 //function : PublishComponent
-//purpose  : 
+//purpose  :
 //=======================================================================
 
 SALOMEDS::SComponent_ptr SMESH_Gen_i::PublishComponent()
@@ -547,9 +547,12 @@ SALOMEDS::SComponent_ptr SMESH_Gen_i::PublishComponent()
   SALOMEDS::StudyBuilder_var    aStudyBuilder  = getStudyServant()->NewBuilder();
   SALOMEDS::UseCaseBuilder_wrap useCaseBuilder = getStudyServant()->GetUseCaseBuilder();
 
-  std::string compDataType = ComponentDataType(); // SMESH module's data type
-  std::string ior = SMESH_Gen_i::GetORB()->object_to_string( SMESH_Gen::_this() ); // IOR of this SMESH engine
-
+  CORBA::String_var compDataType = ComponentDataType(); // SMESH module's data type
+  std::string ior;
+  {
+    CORBA::String_var iorString = GetORB()->object_to_string( SMESH_Gen::_this() );
+    ior = std::string( iorString.in() ); // IOR of this SMESH engine
+  }
   // Find study component which corresponds to this SMESH engine
 
   SALOMEDS::SComponent_wrap father;
@@ -558,12 +561,14 @@ SALOMEDS::SComponent_ptr SMESH_Gen_i::PublishComponent()
     SALOMEDS::SComponent_wrap f_i = citer->Value();
     CORBA::String_var ior_i;
     bool ok = f_i->ComponentIOR(ior_i.out());
-    if ( ok && compDataType == f_i->ComponentDataType() && ior == ior_i.in()) {
+    CORBA::String_var cdt(f_i->ComponentDataType());
+    if ( ok && strcmp( compDataType.in(), cdt.in() ) == 0 && ior == ior_i.in())
+    {
       father = f_i;
       break;
     }
   }
-  
+
   if ( !CORBA::is_nil( father ) ) {
     // check that the component is added to the use case browser
     if ( !useCaseBuilder->IsUseCaseNode( father ) ) {
@@ -579,14 +584,14 @@ SALOMEDS::SComponent_ptr SMESH_Gen_i::PublishComponent()
   if ( CORBA::is_nil( aCat ) )
     return father._retn();
 
-  SALOME_ModuleCatalog::Acomponent_var aComp = aCat->GetComponent( compDataType.c_str() );
+  SALOME_ModuleCatalog::Acomponent_var aComp = aCat->GetComponent( compDataType.in() );
   if ( CORBA::is_nil( aComp ) )
     return father._retn();
 
   SALOMEDS::GenericAttribute_wrap anAttr;
   SALOMEDS::AttributePixMap_wrap  aPixmap;
 
-  father  = aStudyBuilder->NewComponent( compDataType.c_str() );
+  father  = aStudyBuilder->NewComponent( compDataType.in() );
   aStudyBuilder->DefineComponentInstance( father, SMESH_Gen::_this() );
   anAttr  = aStudyBuilder->FindOrCreateAttribute( father, "AttributePixMap" );
   aPixmap = anAttr;
index 838a77ebeb9cf736878cc99202dc1af9e40732b1..cb9cdb5d4dd7c40d2629dd1659c218031cd768aa 100644 (file)
@@ -53,6 +53,8 @@
 
 #include "SMESH_TryCatch.hxx"
 
+#include <memory>
+
 #include CORBA_SERVER_HEADER(SALOME_Session)
 
 using namespace std;
@@ -262,8 +264,8 @@ namespace
 
     if ( !data.empty() )
     {
-      hdf_size datasetSize[] = { data.size() };
-      HDFarray* anArray = new HDFarray(0, HDF_INT32, 1, datasetSize);
+      hdf_size *datasetSize = new hdf_size[1]; datasetSize[0] = data.size();
+      std::unique_ptr<HDFarray> anArray( new HDFarray(0, HDF_INT32, 1, datasetSize) );
       anArray->CreateOnDisk();
       datasetSize[0] = 1;
       HDFdataset* dataset = new HDFdataset( name.c_str(), hdfGroup, HDF_ARRAY, datasetSize, 1 );
index d79d2c285aac26bba3f968a3ba29a19e533191fd..0b2974282d49acc8629b40b7f116fdaf5693eaed 100644 (file)
@@ -28,7 +28,7 @@
 #-------------------------------------------------------------------------
 #
 import salome
-salome.salome_init()
+salome.salome_init_without_session()
 import GEOM
 from salome.geom import geomBuilder
 geompy = geomBuilder.New()
index 4cd1d70c857cb977877930b454e9fae831a19425..1e424cbddfe1485cc222f4eed20412023f0ffcb7 100644 (file)
@@ -27,7 +27,7 @@
 #  $Header$
 #
 import salome
-salome.salome_init()
+salome.salome_init_without_session()
 import GEOM
 from salome.geom import geomBuilder
 geompy = geomBuilder.New()
index 6fecaa29364317331f76f00a48da8c43f582d639..a912dd8bee191886cc9f9c0bf0c04459f0d74396 100644 (file)
@@ -1118,7 +1118,7 @@ bool StdMeshers_Hexa_3D::IsApplicable( const TopoDS_Shape & aShape, bool toCheck
     if ( nbFoundShells != 1 ) {
       if ( toCheckAll ) return false;
       continue;
-    }   
+    }
     exp1.Init( exp0.Current(), TopAbs_FACE );
     int nbEdges = SMESH_MesherHelper::Count( exp1.Current(), TopAbs_EDGE, /*ignoreSame=*/true );
     bool ok = ( nbEdges > 3 );
@@ -1130,7 +1130,7 @@ bool StdMeshers_Hexa_3D::IsApplicable( const TopoDS_Shape & aShape, bool toCheck
 
 //=======================================================================
 //function : ComputePentahedralMesh
-//purpose  : 
+//purpose  :
 //=======================================================================
 
 SMESH_ComputeErrorPtr ComputePentahedralMesh(SMESH_Mesh &          aMesh,
@@ -1138,12 +1138,7 @@ SMESH_ComputeErrorPtr ComputePentahedralMesh(SMESH_Mesh &          aMesh,
                                              SMESH_ProxyMesh*      proxyMesh)
 {
   SMESH_ComputeErrorPtr err = SMESH_ComputeError::New();
-  if ( proxyMesh )
-  {
-    err->myName = COMPERR_BAD_INPUT_MESH;
-    err->myComment = "Can't build pentahedral mesh on viscous layers";
-    return err;
-  }
+
   bool bOK;
   StdMeshers_Penta_3D anAlgo;
   //
@@ -1165,13 +1160,31 @@ SMESH_ComputeErrorPtr ComputePentahedralMesh(SMESH_Mesh &          aMesh,
       err = aPrism3D->GetComputeError();
     }
   }
+  if ( !bOK && proxyMesh )
+  {
+    // check if VL elements are present on block FACEs
+    bool hasVLonFace = false;
+    for ( TopExp_Explorer exp( aShape, TopAbs_FACE ); exp.More(); exp.Next() )
+    {
+      const SMESHDS_SubMesh* sm1 = aMesh.GetSubMesh( exp.Current() )->GetSubMeshDS();
+      const SMESHDS_SubMesh* sm2 = proxyMesh->GetSubMesh( exp.Current() );
+      if (( hasVLonFace = ( sm2 && sm1->NbElements() != sm2->NbElements() )))
+        break;
+    }
+    if ( hasVLonFace )
+    {
+      err->myName = COMPERR_BAD_INPUT_MESH;
+      err->myComment = "Can't build pentahedral mesh on viscous layers";
+    }
+  }
+
   return err;
 }
 
 
 //=======================================================================
 //function : EvaluatePentahedralMesh
-//purpose  : 
+//purpose  :
 //=======================================================================
 
 bool EvaluatePentahedralMesh(SMESH_Mesh & aMesh,
index 15490846958af42bb33a46bde5243a33355c7ebf..fa4853668d343c773397d41e15204a78b3aa44b7 100644 (file)
 #include "SMESH_subMeshEventListener.hxx"
 #include "StdMeshers_FaceSide.hxx"
 #include "StdMeshers_ProjectionUtils.hxx"
+#include "StdMeshers_Quadrangle_2D.hxx"
 #include "StdMeshers_ViscousLayers2D.hxx"
 
 #include <Adaptor3d_HSurface.hxx>
 #include <BRepAdaptor_Curve.hxx>
 #include <BRepAdaptor_Curve2d.hxx>
 #include <BRepAdaptor_Surface.hxx>
-//#include <BRepLProp_CLProps.hxx>
 #include <BRepLProp_SLProps.hxx>
 #include <BRepOffsetAPI_MakeOffsetShape.hxx>
 #include <BRep_Tool.hxx>
 #include <unordered_map>
 
 #ifdef _DEBUG_
-//#define __myDEBUG
+#ifndef WIN32
+#define __myDEBUG
+#endif
 //#define __NOT_INVALIDATE_BAD_SMOOTH
 //#define __NODES_AT_POS
 #endif
@@ -385,6 +387,7 @@ namespace VISCOUS_3D
   struct _LayerEdge;
   struct _EdgesOnShape;
   struct _Smoother1D;
+  struct _Mapper2D;
   typedef map< const SMDS_MeshNode*, _LayerEdge*, TIDCompare > TNode2Edge;
 
   //--------------------------------------------------------------------------------
@@ -444,6 +447,10 @@ namespace VISCOUS_3D
                          const TopoDS_Face&    F,
                          _EdgesOnShape&        eos,
                          SMESH_MesherHelper&   helper );
+    bool UpdatePositionOnSWOL( SMDS_MeshNode*      n,
+                               double              tol,
+                               _EdgesOnShape&      eos,
+                               SMESH_MesherHelper& helper );
     void SetDataByNeighbors( const SMDS_MeshNode* n1,
                              const SMDS_MeshNode* n2,
                              const _EdgesOnShape& eos,
@@ -494,7 +501,7 @@ namespace VISCOUS_3D
     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 );
+    double 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
@@ -623,6 +630,20 @@ namespace VISCOUS_3D
     bool   ToCreateGroup()     const { return !_groupName.empty(); }
     const std::string& GetGroupName() const { return _groupName; }
 
+    double Get1stLayerThickness( double realThickness = 0.) const
+    {
+      const double T = ( realThickness > 0 ) ? realThickness : GetTotalThickness();
+      const double f = GetStretchFactor();
+      const int    N = GetNumberLayers();
+      const double fPowN = pow( f, N );
+      double h0;
+      if ( fPowN - 1 <= numeric_limits<double>::min() )
+        h0 = T / N;
+      else
+        h0 = T * ( f - 1 )/( fPowN - 1 );
+      return h0;
+    }
+
     bool   UseSurfaceNormal()  const
     { return _method == StdMeshers_ViscousLayers::SURF_OFFSET_SMOOTH; }
     bool   ToSmooth()          const
@@ -672,6 +693,8 @@ namespace VISCOUS_3D
 
     Handle(ShapeAnalysis_Surface) _offsetSurf;
     _LayerEdge*                   _edgeForOffset;
+    double                        _offsetValue;
+    _Mapper2D*                    _mapper2D;
 
     _SolidData*            _data; // parent SOLID
 
@@ -685,8 +708,11 @@ namespace VISCOUS_3D
     { return std::find( _eosC1.begin(), _eosC1.end(), other ) != _eosC1.end(); }
     bool             GetNormal( const SMDS_MeshElement* face, gp_Vec& norm );
     _SolidData&      GetData() const { return *_data; }
+    char             ShapeTypeLetter() const
+    { switch ( ShapeType() ) { case TopAbs_FACE: return 'F'; case TopAbs_EDGE: return 'E';
+      case TopAbs_VERTEX: return 'V'; default: return 'S'; }}
 
-    _EdgesOnShape(): _shapeID(-1), _subMesh(0), _toSmooth(false), _edgeSmoother(0) {}
+    _EdgesOnShape(): _shapeID(-1), _subMesh(0), _toSmooth(false), _edgeSmoother(0), _mapper2D(0) {}
     ~_EdgesOnShape();
   };
 
@@ -925,7 +951,7 @@ namespace VISCOUS_3D
                         const StdMeshers_ViscousLayers* hyp,
                         const TopoDS_Shape&             hypShape,
                         set<TGeomID>&                   ignoreFaces);
-    void makeEdgesOnShape();
+    int makeEdgesOnShape();
     bool makeLayer(_SolidData& data);
     void setShapeData( _EdgesOnShape& eos, SMESH_subMesh* sm, _SolidData& data );
     bool setEdgeData( _LayerEdge& edge, _EdgesOnShape& eos,
@@ -1105,6 +1131,22 @@ namespace VISCOUS_3D
 
     void offPointsToPython() const; // debug
   };
+
+  //--------------------------------------------------------------------------------
+  /*!
+   * \brief Compute positions of nodes of 2D structured mesh using TFI
+   */
+  class _Mapper2D
+  {
+    FaceQuadStruct _quadPoints;
+
+    UVPtStruct& uvPnt( size_t i, size_t j ) { return _quadPoints.UVPt( i, j ); }
+
+  public:
+    _Mapper2D( const TParam2ColumnMap & param2ColumnMap, const TNode2Edge& n2eMap );
+    bool ComputeNodePositions();
+  };
+
   //--------------------------------------------------------------------------------
   /*!
    * \brief Class of temporary mesh face.
@@ -1438,17 +1480,42 @@ SMDS_MeshGroup* StdMeshers_ViscousLayers::CreateGroup( const std::string&  theNa
 
 namespace VISCOUS_3D
 {
-  gp_XYZ getEdgeDir( const TopoDS_Edge& E, const TopoDS_Vertex& fromV )
+  gp_XYZ getEdgeDir( const TopoDS_Edge& E, const TopoDS_Vertex& fromV,
+                     const double h0, bool* isRegularEdge = nullptr )
   {
     gp_Vec dir;
     double f,l;
     Handle(Geom_Curve) c = BRep_Tool::Curve( E, f, l );
     if ( c.IsNull() ) return gp_XYZ( Precision::Infinite(), 1e100, 1e100 );
-    gp_Pnt p = BRep_Tool::Pnt( fromV );
-    double distF = p.SquareDistance( c->Value( f ));
-    double distL = p.SquareDistance( c->Value( l ));
+    gp_Pnt  p = BRep_Tool::Pnt( fromV );
+    gp_Pnt pf = c->Value( f ), pl = c->Value( l );
+    double distF = p.SquareDistance( pf );
+    double distL = p.SquareDistance( pl );
     c->D1(( distF < distL ? f : l), p, dir );
     if ( distL < distF ) dir.Reverse();
+    bool isDifficult = false;
+    if ( dir.SquareMagnitude() < h0 * h0 ) // check dir orientation
+    {
+      gp_Pnt& pClose = distF < distL ? pf : pl;
+      gp_Pnt&   pFar = distF < distL ? pl : pf;
+      gp_Pnt    pMid = 0.9 * pClose.XYZ() + 0.1 * pFar.XYZ();
+      gp_Vec vMid( p, pMid );
+      double     dot = vMid * dir;
+      double    cos2 = dot * dot / dir.SquareMagnitude() / vMid.SquareMagnitude();
+      if ( cos2 < 0.7 * 0.7 || dot < 0 ) // large angle between dir and vMid
+      {
+        double uClose = distF < distL ? f : l;
+        double   uFar = distF < distL ? l : f;
+        double      r = h0 / SMESH_Algo::EdgeLength( E );
+        double   uMid = ( 1 - r ) * uClose + r * uFar;
+        pMid = c->Value( uMid );
+        dir = gp_Vec( p, pMid );
+        isDifficult = true;
+      }
+    }
+    if ( isRegularEdge )
+      *isRegularEdge = !isDifficult;
+
     return dir.XYZ();
   }
   //--------------------------------------------------------------------------------
@@ -1465,8 +1532,8 @@ namespace VISCOUS_3D
   }
   //--------------------------------------------------------------------------------
   gp_XYZ getFaceDir( const TopoDS_Face& F, const TopoDS_Vertex& fromV,
-                     const SMDS_MeshNode* node, SMESH_MesherHelper& helper, bool& ok,
-                     double* cosin=0);
+                     const SMDS_MeshNode* node, SMESH_MesherHelper& helper, bool& ok/*,
+                     double* cosin=0*/);
   //--------------------------------------------------------------------------------
   gp_XYZ getFaceDir( const TopoDS_Face& F, const TopoDS_Edge& fromE,
                      const SMDS_MeshNode* node, SMESH_MesherHelper& helper, bool& ok)
@@ -1507,7 +1574,7 @@ namespace VISCOUS_3D
   //--------------------------------------------------------------------------------
   gp_XYZ getFaceDir( const TopoDS_Face& F, const TopoDS_Vertex& fromV,
                      const SMDS_MeshNode* node, SMESH_MesherHelper& helper,
-                     bool& ok, double* cosin)
+                     bool& ok/*, double* cosin*/)
   {
     TopoDS_Face faceFrw = F;
     faceFrw.Orientation( TopAbs_FORWARD );
@@ -1539,7 +1606,7 @@ namespace VISCOUS_3D
       ok = true;
       for ( size_t i = 0; i < nbEdges && ok; ++i )
       {
-        edgeDir[i] = getEdgeDir( edges[i], fromV );
+        edgeDir[i] = getEdgeDir( edges[i], fromV, 0.1 * SMESH_Algo::EdgeLength( edges[i] ));
         double size2 = edgeDir[i].SquareModulus();
         if (( ok = size2 > numeric_limits<double>::min() ))
           edgeDir[i] /= sqrt( size2 );
@@ -1559,15 +1626,15 @@ namespace VISCOUS_3D
         if ( angle < 0 )
           dir.Reverse();
       }
-      if ( cosin ) {
-        double angle = gp_Vec( edgeDir[0] ).Angle( dir );
-        *cosin = Cos( angle );
-      }
+      // if ( cosin ) {
+      //   double angle = faceNormal.Angle( dir );
+      //   *cosin = Cos( angle );
+      // }
     }
     else if ( nbEdges == 1 )
     {
       dir = getFaceDir( faceFrw, edges[ edges[0].IsNull() ], node, helper, ok );
-      if ( cosin ) *cosin = 1.;
+      //if ( cosin ) *cosin = 1.;
     }
     else
     {
@@ -1761,8 +1828,8 @@ namespace VISCOUS_3D
 
   //--------------------------------------------------------------------------------
   // DEBUG. Dump intermediate node positions into a python script
-  // HOWTO use: run python commands written in a console to see
-  //  construction steps of viscous layers
+  // HOWTO use: run python commands written in a console and defined in /tmp/viscous.py
+  // to see construction steps of viscous layers
 #ifdef __myDEBUG
   ostream* py;
   int      theNbPyFunc;
@@ -1963,9 +2030,6 @@ SMESH_ComputeErrorPtr _ViscousBuilder::Compute(SMESH_Mesh&         theMesh,
   if ( _ViscousListener::GetSolidMesh( _mesh, exp.Current(), /*toCreate=*/false))
     return SMESH_ComputeErrorPtr(); // everything already computed
 
-  PyDump debugDump( theMesh );
-  _pyDump = &debugDump;
-
   // TODO: ignore already computed SOLIDs
   if ( !findSolidsWithLayers())
     return _error;
@@ -1973,16 +2037,15 @@ SMESH_ComputeErrorPtr _ViscousBuilder::Compute(SMESH_Mesh&         theMesh,
   if ( !findFacesWithLayers() )
     return _error;
 
-  // for ( size_t i = 0; i < _sdVec.size(); ++i )
-  // {
-  //   if ( ! makeLayer( _sdVec[ i ]))   // create _LayerEdge's
-  //     return _error;
-  // }
-
-  makeEdgesOnShape();
+  if ( !makeEdgesOnShape() )
+    return _error;
 
   findPeriodicFaces();
 
+  PyDump debugDump( theMesh );
+  _pyDump = &debugDump;
+
+
   for ( size_t i = 0; i < _sdVec.size(); ++i )
   {
     size_t iSD = 0;
@@ -1991,6 +2054,8 @@ SMESH_ComputeErrorPtr _ViscousBuilder::Compute(SMESH_Mesh&         theMesh,
            !_sdVec[iSD]._solid.IsNull() &&
            !_sdVec[iSD]._done )
         break;
+    if ( iSD == _sdVec.size() )
+      break; // all done
 
     if ( ! makeLayer(_sdVec[iSD]) )   // create _LayerEdge's
       return _error;
@@ -2617,6 +2682,7 @@ bool _ViscousBuilder::makeLayer(_SolidData& data)
 
   // Create temporary faces and _LayerEdge's
 
+  debugMsg( "######################" );
   dumpFunction(SMESH_Comment("makeLayers_")<<data._index);
 
   vector< _EdgesOnShape >& edgesByGeom = data._edgesOnShape;
@@ -2677,7 +2743,7 @@ bool _ViscousBuilder::makeLayer(_SolidData& data)
             nbDegenNodes++;
           }
         }
-        TNode2Edge::iterator n2e = data._n2eMap.insert( make_pair( n, (_LayerEdge*)0 )).first;
+        TNode2Edge::iterator n2e = data._n2eMap.insert({ n, nullptr }).first;
         if ( !(*n2e).second )
         {
           // add a _LayerEdge
@@ -2711,13 +2777,12 @@ bool _ViscousBuilder::makeLayer(_SolidData& data)
             if ( !setEdgeData( *edge, edgesByGeom[ shapeID ], helper, data ))
               return false;
 
-            if ( edge->_nodes.size() < 2 )
-              edge->Block( data );
-              //data._noShrinkShapes.insert( shapeID );
+            if ( edge->_nodes.size() < 2 && !noShrink )
+              edge->Block( data ); // a sole node is moved only if noShrink
           }
           dumpMove(edge->_nodes.back());
 
-          if ( edge->_cosin > faceMaxCosin )
+          if ( edge->_cosin > faceMaxCosin && edge->_nodes.size() > 1 )
           {
             faceMaxCosin = edge->_cosin;
             maxCosinEdge = edge;
@@ -2767,6 +2832,42 @@ bool _ViscousBuilder::makeLayer(_SolidData& data)
         if (( n2e = data._n2eMap.find( *node )) != data._n2eMap.end() )
           edge->_neibors.push_back( n2e->second );
     }
+
+    // Fix uv of nodes on periodic FACEs (bos #20643)
+
+    if ( eos.ShapeType() != TopAbs_EDGE ||
+         eos.SWOLType()  != TopAbs_FACE ||
+         eos.size() == 0 )
+      continue;
+
+    const TopoDS_Face& F = TopoDS::Face( eos._sWOL );
+    SMESH_MesherHelper faceHelper( *_mesh );
+    faceHelper.SetSubShape( F );
+    faceHelper.ToFixNodeParameters( true );
+    if ( faceHelper.GetPeriodicIndex() == 0 )
+      continue;
+
+    SMESHDS_SubMesh* smDS = getMeshDS()->MeshElements( F );
+    if ( !smDS || smDS->GetNodes() == 0 )
+      continue;
+
+    bool toCheck = true;
+    const double tol = 2 * helper.MaxTolerance( F );
+    for ( SMDS_NodeIteratorPtr nIt = smDS->GetNodes(); nIt->more(); )
+    {
+      const SMDS_MeshNode* node = nIt->next();
+      gp_XY uvNew( Precision::Infinite(), 0 );
+      if ( toCheck )
+      {
+        toCheck = false;
+        gp_XY uv = faceHelper.GetNodeUV( F, node );
+        if ( ! faceHelper.CheckNodeUV( F, node, uvNew, tol, /*force=*/true ))
+          break; // projection on F failed
+        if (( uv - uvNew ).Modulus() < Precision::Confusion() )
+          break; // current uv is OK
+      }
+      faceHelper.CheckNodeUV( F, node, uvNew, tol, /*force=*/true );
+    }
   }
 
   data._epsilon = 1e-7;
@@ -3120,13 +3221,13 @@ bool _ViscousBuilder::findShapesToSmooth( _SolidData& data )
     if ( SMESH_Algo::isDegenerated( E ) || !edgesOfSmooFaces.Contains( E ))
       continue;
 
-    double tgtThick = eos._hyp.GetTotalThickness();
+    double tgtThick = eos._hyp.GetTotalThickness(), h0 = eos._hyp.Get1stLayerThickness();
     for ( TopoDS_Iterator vIt( E ); vIt.More() && !eos._toSmooth; vIt.Next() )
     {
       TGeomID iV = getMeshDS()->ShapeToIndex( vIt.Value() );
       vector<_LayerEdge*>& eV = edgesByGeom[ iV ]._edges;
       if ( eV.empty() || eV[0]->Is( _LayerEdge::MULTI_NORMAL )) continue;
-      gp_Vec  eDir    = getEdgeDir( E, TopoDS::Vertex( vIt.Value() ));
+      gp_Vec  eDir    = getEdgeDir( E, TopoDS::Vertex( vIt.Value() ), h0 );
       double angle    = eDir.Angle( eV[0]->_normal );
       double cosin    = Cos( angle );
       double cosinAbs = Abs( cosin );
@@ -3304,7 +3405,7 @@ bool _ViscousBuilder::findShapesToSmooth( _SolidData& data )
     {
       _EdgesOnShape* eoe = data.GetShapeEdges( *e );
       if ( !eoe ) continue; // other solid
-      gp_XYZ eDir = getEdgeDir( TopoDS::Edge( *e ), V );
+      gp_XYZ eDir = getEdgeDir( TopoDS::Edge( *e ), V, eoe->_hyp.Get1stLayerThickness() );
       if ( !Precision::IsInfinite( eDir.X() ))
         dirOfEdges.push_back( make_pair( eoe, eDir.Normalized() ));
     }
@@ -3350,9 +3451,10 @@ bool _ViscousBuilder::findShapesToSmooth( _SolidData& data )
  */
 //================================================================================
 
-void _ViscousBuilder::makeEdgesOnShape()
+int _ViscousBuilder::makeEdgesOnShape()
 {
   const int nbShapes = getMeshDS()->MaxShapeIndex();
+  int nbSolidsWL = 0;
 
   for ( size_t i = 0; i < _sdVec.size(); ++i )
   {
@@ -3361,6 +3463,7 @@ void _ViscousBuilder::makeEdgesOnShape()
     edgesByGeom.resize( nbShapes+1 );
 
     // set data of _EdgesOnShape's
+    int nbShapesWL = 0;
     if ( SMESH_subMesh* sm = _mesh->GetSubMesh( data._solid ))
     {
       SMESH_subMeshIteratorPtr smIt = sm->getDependsOnIterator(/*includeSelf=*/false);
@@ -3372,9 +3475,21 @@ void _ViscousBuilder::makeEdgesOnShape()
           continue;
 
         setShapeData( edgesByGeom[ sm->GetId() ], sm, data );
+
+        nbShapesWL += ( sm->GetSubShape().ShapeType() == TopAbs_FACE );
       }
     }
+    if ( nbShapesWL == 0 ) // no shapes with layers in a SOLID
+    {
+      data._done = true;
+      SMESHUtils::FreeVector( edgesByGeom );
+    }
+    else
+    {
+      ++nbSolidsWL;
+    }
   }
+  return nbSolidsWL;
 }
 
 //================================================================================
@@ -3400,6 +3515,7 @@ void _ViscousBuilder::setShapeData( _EdgesOnShape& eos,
     eos._shape.Orientation( helper.GetSubShapeOri( data._solid, eos._shape ));
   eos._toSmooth = false;
   eos._data = &data;
+  eos._mapper2D = nullptr;
 
   // set _SWOL
   map< TGeomID, TopoDS_Shape >::const_iterator s2s =
@@ -3520,6 +3636,7 @@ bool _EdgesOnShape::GetNormal( const SMDS_MeshElement* face, gp_Vec& norm )
 _EdgesOnShape::~_EdgesOnShape()
 {
   delete _edgeSmoother;
+  delete _mapper2D;
 }
 
 //================================================================================
@@ -3601,13 +3718,14 @@ bool _ViscousBuilder::setEdgeData(_LayerEdge&         edge,
       if ( eos.SWOLType() == TopAbs_EDGE )
       {
         // inflate from VERTEX along EDGE
-        edge._normal = getEdgeDir( TopoDS::Edge( eos._sWOL ), TopoDS::Vertex( eos._shape ));
+        edge._normal = getEdgeDir( TopoDS::Edge( eos._sWOL ), TopoDS::Vertex( eos._shape ),
+                                   eos._hyp.Get1stLayerThickness(), &eos._isRegularSWOL );
       }
       else if ( eos.ShapeType() == TopAbs_VERTEX )
       {
         // inflate from VERTEX along FACE
         edge._normal = getFaceDir( TopoDS::Face( eos._sWOL ), TopoDS::Vertex( eos._shape ),
-                                   node, helper, normOK, &edge._cosin);
+                                   node, helper, normOK/*, &edge._cosin*/);
       }
       else
       {
@@ -3696,30 +3814,37 @@ bool _ViscousBuilder::setEdgeData(_LayerEdge&         edge,
       break;
     }
     case TopAbs_VERTEX: {
+      TopoDS_Vertex V  = TopoDS::Vertex( eos._shape );
+      gp_Vec inFaceDir = getFaceDir( face2Norm[0].first , V, node, helper, normOK );
+      double angle     = inFaceDir.Angle( edge._normal ); // [0,PI]
+      edge._cosin      = Cos( angle );
       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 = 1; iF < totalNbFaces; ++iF )
-          {
-            F = face2Norm[ iF ].first;
-            inFaceDir = getFaceDir( F, V, node, helper, normOK=true );
-            if ( normOK ) {
-              double angle = inFaceDir.Angle( edge._normal );
-              double cosin = Cos( angle );
-              if ( Abs( cosin ) > Abs( edge._cosin ))
-                edge._cosin = cosin;
+        totalNbFaces--;
+      if ( totalNbFaces > 1 || helper.IsSeamShape( node->getshapeId() ))
+        for ( int iF = 1; iF < totalNbFaces; ++iF )
+        {
+          F = face2Norm[ iF ].first;
+          inFaceDir = getFaceDir( F, V, node, helper, normOK=true );
+          if ( normOK ) {
+            if ( onShrinkShape )
+            {
+              gp_Vec faceNorm = getFaceNormal( node, F, helper, normOK );
+              if ( !normOK ) continue;
+              if ( helper.GetSubShapeOri( data._solid, F ) != TopAbs_REVERSED )
+                faceNorm.Reverse();
+              angle = 0.5 * M_PI - faceNorm.Angle( edge._normal );
+              if ( inFaceDir * edge._normal < 0 )
+                angle = M_PI - angle;
             }
+            else
+            {
+              angle = inFaceDir.Angle( edge._normal );
+            }
+            double cosin = Cos( angle );
+            if ( Abs( cosin ) > Abs( edge._cosin ))
+              edge._cosin = cosin;
           }
-      }
+        }
       break;
     }
     default:
@@ -3744,7 +3869,20 @@ bool _ViscousBuilder::setEdgeData(_LayerEdge&         edge,
   // Set the rest data
   // --------------------
 
-  edge.SetCosin( edge._cosin ); // to update edge._lenFactor
+  double realLenFactor = edge.SetCosin( edge._cosin ); // to update edge._lenFactor
+  // if ( realLenFactor > 3 )
+  // {
+  //   edge._cosin = 1;
+  //   if ( onShrinkShape )
+  //   {
+  //     edge.Set( _LayerEdge::RISKY_SWOL );
+  //     edge._lenFactor = 2;
+  //   }
+  //   else
+  //   {
+  //     edge._lenFactor = 1;
+  //   }
+  // }
 
   if ( onShrinkShape )
   {
@@ -3768,7 +3906,7 @@ bool _ViscousBuilder::setEdgeData(_LayerEdge&         edge,
         getMeshDS()->SetNodeOnFace( tgtNode, TopoDS::Face( eos._sWOL ), uv.X(), uv.Y() );
     }
 
-    if ( edge._nodes.size() > 1 )
+    //if ( edge._nodes.size() > 1 ) -- allow RISKY_SWOL on noShrink shape
     {
       // check if an angle between a FACE with layers and SWOL is sharp,
       // else the edge should not inflate
@@ -3783,10 +3921,14 @@ bool _ViscousBuilder::setEdgeData(_LayerEdge&         edge,
           geomNorm.Reverse(); // inside the SOLID
         if ( geomNorm * edge._normal < -0.001 )
         {
-          getMeshDS()->RemoveFreeNode( tgtNode, 0, /*fromGroups=*/false );
-          edge._nodes.resize( 1 );
+          if ( edge._nodes.size() > 1 )
+          {
+            getMeshDS()->RemoveFreeNode( tgtNode, 0, /*fromGroups=*/false );
+            edge._nodes.resize( 1 );
+          }
         }
-        else if ( edge._lenFactor > 3 )
+        else if ( realLenFactor > 3 ) ///  -- moved to SetCosin()
+          //else if ( edge._lenFactor > 3 )
         {
           edge._lenFactor = 2;
           edge.Set( _LayerEdge::RISKY_SWOL );
@@ -4153,7 +4295,7 @@ void _OffsetPlane::ComputeIntersectionLine( _OffsetPlane&        pln,
     // parallel planes - intersection is an offset of the common EDGE
     gp_Pnt p = BRep_Tool::Pnt( V );
     linePos  = 0.5 * (( p.XYZ() + n1 ) + ( p.XYZ() + n2 ));
-    lineDir  = getEdgeDir( E, V );
+    lineDir  = getEdgeDir( E, V, 0.1 * SMESH_Algo::EdgeLength( E ));
   }
   else
   {
@@ -4404,12 +4546,23 @@ gp_XYZ _LayerEdge::Copy( _LayerEdge&         other,
  */
 //================================================================================
 
-void _LayerEdge::SetCosin( double cosin )
+double _LayerEdge::SetCosin( double cosin )
 {
   _cosin = cosin;
   cosin = Abs( _cosin );
-  //_lenFactor = ( cosin < 1.-1e-12 ) ?  Min( 2., 1./sqrt(1-cosin*cosin )) : 1.0;
-  _lenFactor = ( cosin < 1.-1e-12 ) ?  1./sqrt(1-cosin*cosin ) : 1.0;
+  //_lenFactor = ( cosin < 1.-1e-12 ) ?  1./sqrt(1-cosin*cosin ) : 1.0;
+  double realLenFactor;
+  if ( cosin < 1.-1e-12 )
+  {
+    _lenFactor = realLenFactor = 1./sqrt(1-cosin*cosin );
+  }
+  else
+  {
+    _lenFactor = 1;
+    realLenFactor = Precision::Infinite();
+  }
+
+  return realLenFactor;
 }
 
 //================================================================================
@@ -4590,7 +4743,7 @@ void _ViscousBuilder::computeGeomSize( _SolidData& data )
     double thinkness = eos._hyp.GetTotalThickness();
     for ( size_t i = 0; i < eos._edges.size(); ++i )
     {
-      if ( eos._edges[i]->Is( _LayerEdge::BLOCKED )) continue;
+      if ( eos._edges[i]->_nodes.size() < 2 ) continue;
       eos._edges[i]->SetMaxLen( thinkness );
       eos._edges[i]->FindIntersection( *searcher, intersecDist, data._epsilon, eos, &face );
       if ( intersecDist > 0 && face )
@@ -4781,7 +4934,7 @@ bool _ViscousBuilder::inflate(_SolidData& data)
         if ( eos._edges[i]->_nodes.size() > 1 )
           avgThick    += Min( 1., eos._edges[i]->_len / shapeTgtThick );
         else
-          avgThick    += shapeTgtThick;
+          avgThick    += 1;
         nbActiveEdges += ( ! eos._edges[i]->Is( _LayerEdge::BLOCKED ));
       }
     }
@@ -4962,24 +5115,41 @@ bool _ViscousBuilder::smoothAndCheck(_SolidData& data,
         for ( size_t iEOS = 0; iEOS < eosC1.size(); ++iEOS )
         {
           isConcaveFace[ iEOS ] = data._concaveFaces.count( eosC1[ iEOS ]->_shapeID  );
-          vector< _LayerEdge* > & edges = eosC1[ iEOS ]->_edges;
-          for ( size_t i = 0; i < edges.size(); ++i )
-            if ( edges[i]->Is( _LayerEdge::MOVED ) ||
-                 edges[i]->Is( _LayerEdge::NEAR_BOUNDARY ))
-              movedEdges.push_back( edges[i] );
 
+          if ( eosC1[ iEOS ]->_mapper2D )
+          {
+            // compute node position by boundary node position in structured mesh
+            dumpFunction(SMESH_Comment("map2dS")<<data._index<<"_Fa"<<eos._shapeID
+                         <<"_InfStep"<<infStep);
+
+            eosC1[ iEOS ]->_mapper2D->ComputeNodePositions();
+
+            for ( _LayerEdge* le : eosC1[ iEOS ]->_edges )
+              le->_pos.back() = SMESH_NodeXYZ( le->_nodes.back() );
+
+            dumpFunctionEnd();
+          }
+          else
+          {
+            for ( _LayerEdge* le : eosC1[ iEOS ]->_edges )
+              if ( le->Is( _LayerEdge::MOVED ) ||
+                   le->Is( _LayerEdge::NEAR_BOUNDARY ))
+                movedEdges.push_back( le );
+          }
           makeOffsetSurface( *eosC1[ iEOS ], helper );
         }
 
         int step = 0, stepLimit = 5, nbBad = 0;
         while (( ++step <= stepLimit ) || improved )
         {
-          dumpFunction(SMESH_Comment("smooth")<<data._index<<"_Fa"<<sInd
-                       <<"_InfStep"<<infStep<<"_"<<step); // debug
           int oldBadNb = nbBad;
           badEdges.clear();
 
 #ifdef INCREMENTAL_SMOOTH
+          // smooth moved only
+          if ( !movedEdges.empty() )
+            dumpFunction(SMESH_Comment("smooth")<<data._index<<"_Fa"<<sInd
+                         <<"_InfStep"<<infStep<<"_"<<step); // debug
           bool findBest = false; // ( step == stepLimit );
           for ( size_t i = 0; i < movedEdges.size(); ++i )
           {
@@ -4988,9 +5158,14 @@ bool _ViscousBuilder::smoothAndCheck(_SolidData& data,
               badEdges.push_back( movedEdges[i] );
           }
 #else
+          // smooth all
+          dumpFunction(SMESH_Comment("smooth")<<data._index<<"_Fa"<<sInd
+                       <<"_InfStep"<<infStep<<"_"<<step); // debug
           bool findBest = ( step == stepLimit || isConcaveFace[ iEOS ]);
           for ( size_t iEOS = 0; iEOS < eosC1.size(); ++iEOS )
           {
+            if ( eosC1[ iEOS ]->_mapper2D )
+              continue;
             vector< _LayerEdge* > & edges = eosC1[ iEOS ]->_edges;
             for ( size_t i = 0; i < edges.size(); ++i )
             {
@@ -5061,11 +5236,11 @@ bool _ViscousBuilder::smoothAndCheck(_SolidData& data,
 
         } // smoothing steps
 
-        // project -- to prevent intersections or fix bad simplices
+        // project -- to prevent intersections or to fix bad simplices
         for ( size_t iEOS = 0; iEOS < eosC1.size(); ++iEOS )
         {
           if ( ! eosC1[ iEOS ]->_eosConcaVer.empty() || nbBad > 0 )
-            putOnOffsetSurface( *eosC1[ iEOS ], infStep, eosC1 );
+            putOnOffsetSurface( *eosC1[ iEOS ], -infStep, eosC1 );
         }
 
         //if ( !badEdges.empty() )
@@ -5237,7 +5412,7 @@ bool _ViscousBuilder::smoothAndCheck(_SolidData& data,
           continue;
 
         // ignore intersection with intFace of an adjacent FACE
-        if ( dist > 0.1 * eos._edges[i]->_len )
+        if ( dist > 0.01 * eos._edges[i]->_len )
         {
           bool toIgnore = false;
           if (  eos._toSmooth )
@@ -5273,8 +5448,11 @@ bool _ViscousBuilder::smoothAndCheck(_SolidData& data,
 
         // intersection not ignored
 
-        if ( toBlockInfaltion &&
-             dist < ( eos._edges[i]->_len * theThickToIntersection ))
+        double minDist = 0;
+        if ( eos._edges[i]->_maxLen < 0.99 * eos._hyp.GetTotalThickness() ) // limited length
+          minDist = eos._edges[i]->_len * theThickToIntersection;
+
+        if ( toBlockInfaltion && dist < minDist  )
         {
           if ( is1stBlocked ) { is1stBlocked = false; // debug
             dumpFunction(SMESH_Comment("blockIntersected") <<data._index<<"_InfStep"<<infStep);
@@ -5508,14 +5686,14 @@ void _ViscousBuilder::makeOffsetSurface( _EdgesOnShape& eos, SMESH_MesherHelper&
   // find offset
   gp_Pnt   tgtP = SMESH_TNodeXYZ( eos._edgeForOffset->_nodes.back() );
   /*gp_Pnt2d uv=*/baseSurface->ValueOfUV( tgtP, Precision::Confusion() );
-  double offset = baseSurface->Gap();
+  eos._offsetValue = baseSurface->Gap();
 
   eos._offsetSurf.Nullify();
 
   try
   {
     BRepOffsetAPI_MakeOffsetShape offsetMaker;
-    offsetMaker.PerformByJoin( eos._shape, -offset, Precision::Confusion() );
+    offsetMaker.PerformByJoin( eos._shape, -eos._offsetValue, Precision::Confusion() );
     if ( !offsetMaker.IsDone() ) return;
 
     TopExp_Explorer fExp( offsetMaker.Shape(), TopAbs_FACE );
@@ -5567,6 +5745,7 @@ void _ViscousBuilder::putOnOffsetSurface( _EdgesOnShape&            eos,
     return;
 
   double preci = BRep_Tool::Tolerance( TopoDS::Face( eof->_shape )), vol;
+  bool neighborHasRiskySWOL = false;
   for ( size_t i = 0; i < eos._edges.size(); ++i )
   {
     _LayerEdge* edge = eos._edges[i];
@@ -5578,12 +5757,23 @@ void _ViscousBuilder::putOnOffsetSurface( _EdgesOnShape&            eos,
       if ( !edge->Is( _LayerEdge::UPD_NORMAL_CONV ))
         continue;
     }
+    else if ( moveAll == _LayerEdge::RISKY_SWOL )
+    {
+      if ( !edge->Is( _LayerEdge::RISKY_SWOL ) ||
+           edge->_cosin < 0 )
+        continue;
+    }
     else if ( !moveAll && !edge->Is( _LayerEdge::MOVED ))
       continue;
 
     int nbBlockedAround = 0;
     for ( size_t iN = 0; iN < edge->_neibors.size(); ++iN )
+    {
       nbBlockedAround += edge->_neibors[iN]->Is( _LayerEdge::BLOCKED );
+      if ( edge->_neibors[iN]->Is( _LayerEdge::RISKY_SWOL ) &&
+           edge->_neibors[iN]->_cosin > 0 )
+        neighborHasRiskySWOL = true;
+    }
     if ( nbBlockedAround > 1 )
       continue;
 
@@ -5612,6 +5802,35 @@ void _ViscousBuilder::putOnOffsetSurface( _EdgesOnShape&            eos,
       {
         edge->_normal = ( newP - prevP ).Normalized();
       }
+      // if ( edge->_len < eof->_offsetValue )
+      //   edge->_len = eof->_offsetValue;
+
+      if ( !eos._sWOL.IsNull() ) // RISKY_SWOL
+      {
+        double change = eof->_offsetSurf->Gap() / eof->_offsetValue;
+        if (( newP - tgtP.XYZ() ) * edge->_normal < 0 )
+          change = 1 - change;
+        else
+          change = 1 + change;
+        gp_XYZ shitfVec    = tgtP.XYZ() - SMESH_NodeXYZ( edge->_nodes[0] );
+        gp_XYZ newShiftVec = shitfVec * change;
+        double shift       = edge->_normal * shitfVec;
+        double newShift    = edge->_normal * newShiftVec;
+        newP = tgtP.XYZ() + edge->_normal * ( newShift - shift );
+
+        uv = eof->_offsetSurf->NextValueOfUV( edge->_curvature->_uv, newP, preci );
+        if ( eof->_offsetSurf->Gap() < edge->_len )
+        {
+          edge->_curvature->_uv = uv;
+          newP = eof->_offsetSurf->Value( uv ).XYZ();
+        }
+        n->setXYZ( newP.X(), newP.Y(), newP.Z());
+        if ( !edge->UpdatePositionOnSWOL( n, /*tol=*/10 * edge->_len / ( edge->NbSteps() + 1 ),
+                                          eos, eos.GetData().GetHelper() ))
+        {
+          debugMsg("UpdatePositionOnSWOL fails in putOnOffsetSurface()" );
+        }
+      }
     }
   }
 
@@ -5625,8 +5844,8 @@ void _ViscousBuilder::putOnOffsetSurface( _EdgesOnShape&            eos,
       break;
   if ( i < eos._edges.size() )
   {
-    dumpFunction(SMESH_Comment("putOnOffsetSurface_S") << eos._shapeID
-                 << "_InfStep" << infStep << "_" << smooStep );
+    dumpFunction(SMESH_Comment("putOnOffsetSurface_") << eos.ShapeTypeLetter() << eos._shapeID
+                 << "_InfStep" << infStep << "_" << Abs( smooStep ));
     for ( ; i < eos._edges.size(); ++i )
     {
       if ( eos._edges[i]->Is( _LayerEdge::MARKED )) {
@@ -5647,7 +5866,7 @@ void _ViscousBuilder::putOnOffsetSurface( _EdgesOnShape&            eos,
     SMESH_subMeshIteratorPtr smIt = eos._subMesh->getDependsOnIterator(/*includeSelf=*/false);
     while ( smIt->more() )
     {
-      SMESH_subMesh* sm = smIt->next();
+      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;
@@ -5656,6 +5875,28 @@ void _ViscousBuilder::putOnOffsetSurface( _EdgesOnShape&            eos,
     }
     cnvFace->_normalsFixedOnBorders = true;
   }
+
+
+  // bos #20643
+  // negative smooStep means "final step", where we don't treat RISKY_SWOL edges
+  // as edges based on FACE are a bit late comparing with them
+  if ( smooStep >= 0 &&
+       neighborHasRiskySWOL &&
+       moveAll != _LayerEdge::RISKY_SWOL &&
+       eos.ShapeType() == TopAbs_FACE )
+  {
+    // 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::RISKY_SWOL );
+    }
+  }
 }
 
 //================================================================================
@@ -5958,9 +6199,11 @@ bool _Smoother1D::smoothAnalyticEdge( _SolidData&                    data,
           tgtNode->setXYZ( newPos.X(), newPos.Y(), newPos.Z() );
           dumpMove( tgtNode );
 
-          SMDS_FacePositionPtr pos = tgtNode->GetPosition();
-          pos->SetUParameter( newUV.X() );
-          pos->SetVParameter( newUV.Y() );
+          if ( SMDS_FacePositionPtr pos = tgtNode->GetPosition() ) // NULL if F is noShrink
+          {
+            pos->SetUParameter( newUV.X() );
+            pos->SetVParameter( newUV.Y() );
+          }
 
           gp_XYZ newUV0( newUV.X(), newUV.Y(), 0 );
 
@@ -6070,10 +6313,11 @@ bool _Smoother1D::smoothAnalyticEdge( _SolidData&                    data,
         tgtNode->setXYZ( newPos.X(), newPos.Y(), newPos.Z() );
         dumpMove( tgtNode );
 
-        SMDS_FacePositionPtr pos = tgtNode->GetPosition();
-        pos->SetUParameter( newUV.X() );
-        pos->SetVParameter( newUV.Y() );
-
+        if ( SMDS_FacePositionPtr pos = tgtNode->GetPosition() ) // NULL if F is noShrink
+        {
+          pos->SetUParameter( newUV.X() );
+          pos->SetVParameter( newUV.Y() );
+        }
         _eos[i]->Set( _LayerEdge::SMOOTHED ); // to check in refine() (IPAL54237)
       }
     }
@@ -6330,7 +6574,7 @@ void _Smoother1D::prepare(_SolidData& data)
 
   // divide E to have offset segments with low deflection
   BRepAdaptor_Curve c3dAdaptor( E );
-  const double curDeflect = 0.1; //0.01; // Curvature deflection == |p1p2]*sin(p1p2,p1pM)
+  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 )
@@ -6468,6 +6712,16 @@ gp_XYZ _Smoother1D::getNormalNormal( const gp_XYZ & normal,
   // if ( size == 0 ) // MULTI_NORMAL _LayerEdge
   //   return gp_XYZ( 1e-100, 1e-100, 1e-100 );
 
+  if ( size < 1e-5 ) // normal || edgeDir (almost) at inflation along EDGE (bos #20643)
+  {
+    const _LayerEdge* le = _eos._edges[ _eos._edges.size() / 2 ];
+    const gp_XYZ& leNorm = le->_normal;
+
+    cross = leNorm ^ edgeDir;
+    norm = edgeDir ^ cross;
+    size = norm.Modulus();
+  }
+
   return norm / size;
 }
 
@@ -6695,20 +6949,98 @@ void _SolidData::PrepareEdgesToSmoothOnFace( _EdgesOnShape* eos, bool substitute
     eos->_edgeForOffset = 0;
 
     double maxCosin = -1;
+    //bool hasNoShrink = false;
     for ( TopExp_Explorer eExp( eos->_shape, TopAbs_EDGE ); eExp.More(); eExp.Next() )
     {
       _EdgesOnShape* eoe = GetShapeEdges( eExp.Current() );
       if ( !eoe || eoe->_edges.empty() ) continue;
 
+      // if ( eos->GetData()._noShrinkShapes.count( eoe->_shapeID ))
+      //   hasNoShrink = true;
+
       vector<_LayerEdge*>& eE = eoe->_edges;
       _LayerEdge* e = eE[ eE.size() / 2 ];
-      if ( e->_cosin > maxCosin )
+      if ( !e->Is( _LayerEdge::RISKY_SWOL ) && e->_cosin > maxCosin )
       {
         eos->_edgeForOffset = e;
         maxCosin = e->_cosin;
       }
+
+      if ( !eoe->_sWOL.IsNull() )
+        for ( _LayerEdge* le : eoe->_edges )
+          if ( le->Is( _LayerEdge::RISKY_SWOL ) && e->_cosin > 0 )
+          {
+            // make _neibors on FACE be smoothed after le->Is( BLOCKED )
+            for ( _LayerEdge* neibor : le->_neibors )
+            {
+              int shapeDim =  neibor->BaseShapeDim();
+              if ( shapeDim == 2 )
+                neibor->Set( _LayerEdge::NEAR_BOUNDARY ); // on FACE
+              else if ( shapeDim == 0 )
+                neibor->Set( _LayerEdge::RISKY_SWOL );    // on VERTEX
+
+              if ( !neibor->_curvature )
+              {
+                gp_XY uv = helper.GetNodeUV( F, neibor->_nodes[0] );
+                neibor->_curvature = _Factory::NewCurvature();
+                neibor->_curvature->_r = 0;
+                neibor->_curvature->_k = 0;
+                neibor->_curvature->_h2lenRatio = 0;
+                neibor->_curvature->_uv = uv;
+              }
+            }
+          }
+    } // loop on EDGEs
+
+    // Try to initialize _Mapper2D
+
+    // if ( hasNoShrink )
+    //   return;
+
+    SMDS_ElemIteratorPtr fIt = eos->_subMesh->GetSubMeshDS()->GetElements();
+    if ( !fIt->more() || fIt->next()->NbCornerNodes() != 4 )
+      return;
+
+    // get EDGEs of quadrangle bottom
+    std::list< TopoDS_Edge > edges;
+    std::list< int > nbEdgesInWire;
+    int nbWire = SMESH_Block::GetOrderedEdges( F, edges, nbEdgesInWire );
+    if ( nbWire != 1 || nbEdgesInWire.front() < 4 )
+      return;
+    const SMDS_MeshNode* node;
+    while ( true ) // make edges start at a corner VERTEX
+    {
+      node = SMESH_Algo::VertexNode( helper.IthVertex( 0, edges.front() ), helper.GetMeshDS() );
+      if ( node && helper.IsCornerOfStructure( node, eos->_subMesh->GetSubMeshDS(), helper ))
+        break;
+      edges.pop_front();
+      if ( edges.empty() )
+        return;
+    }
+    std::list< TopoDS_Edge >::iterator edgeIt = edges.begin();
+    while ( true ) // make edges finish at a corner VERTEX
+    {
+      node = SMESH_Algo::VertexNode( helper.IthVertex( 1, *edgeIt ), helper.GetMeshDS() );
+      ++edgeIt;
+      if ( node && helper.IsCornerOfStructure( node, eos->_subMesh->GetSubMeshDS(), helper ))
+      {
+        edges.erase( edgeIt, edges.end() );
+        break;
+      }
+      if ( edgeIt == edges.end() )
+        return;
     }
-  }
+
+    // get structure of nodes
+    TParam2ColumnMap param2ColumnMap;
+    if ( !helper.LoadNodeColumns( param2ColumnMap, F, edges, helper.GetMeshDS() ))
+      return;
+
+    eos->_mapper2D = new _Mapper2D( param2ColumnMap, eos->GetData()._n2eMap );
+
+  } // if eos is of curved FACE
+
+  return;
 }
 
 //================================================================================
@@ -7320,7 +7652,8 @@ bool _ViscousBuilder::updateNormals( _SolidData&         data,
           PShapeIteratorPtr eIt = helper.GetAncestors( V, *_mesh, TopAbs_EDGE, &eos->_sWOL );
           while ( const TopoDS_Shape* E = eIt->next() )
           {
-            gp_Vec edgeDir = getEdgeDir( TopoDS::Edge( *E ), TopoDS::Vertex( V ));
+            gp_Vec edgeDir = getEdgeDir( TopoDS::Edge( *E ), TopoDS::Vertex( V ),
+                                         eos->_hyp.Get1stLayerThickness() );
             double   angle = edgeDir.Angle( newEdge._normal ); // [0,PI]
             if ( angle < M_PI / 2 )
               shapesToSmooth.insert( data.GetShapeEdges( *E ));
@@ -9606,6 +9939,8 @@ void _LayerEdge::SetNewLength( double len, _EdgesOnShape& eos, SMESH_MesherHelpe
     Block( eos.GetData() );
   }
   const double lenDelta = len - _len;
+  // if ( lenDelta < 0 )
+  //   return;
   if ( lenDelta < len * 1e-3  )
   {
     Block( eos.GetData() );
@@ -9649,46 +9984,13 @@ void _LayerEdge::SetNewLength( double len, _EdgesOnShape& eos, SMESH_MesherHelpe
   _pos.push_back( newXYZ );
 
   if ( !eos._sWOL.IsNull() )
-  {
-    double distXYZ[4];
-    bool uvOK = false;
-    if ( eos.SWOLType() == TopAbs_EDGE )
-    {
-      double u = Precision::Infinite(); // to force projection w/o distance check
-      uvOK = helper.CheckNodeU( TopoDS::Edge( eos._sWOL ), n, u,
-                                /*tol=*/2*lenDelta, /*force=*/true, distXYZ );
-      _pos.back().SetCoord( u, 0, 0 );
-      if ( _nodes.size() > 1 && uvOK )
-      {
-        SMDS_EdgePositionPtr pos = n->GetPosition();
-        pos->SetUParameter( u );
-      }
-    }
-    else //  TopAbs_FACE
-    {
-      gp_XY uv( Precision::Infinite(), 0 );
-      uvOK = helper.CheckNodeUV( TopoDS::Face( eos._sWOL ), n, uv,
-                                 /*tol=*/2*lenDelta, /*force=*/true, distXYZ );
-      _pos.back().SetCoord( uv.X(), uv.Y(), 0 );
-      if ( _nodes.size() > 1 && uvOK )
-      {
-        SMDS_FacePositionPtr pos = n->GetPosition();
-        pos->SetUParameter( uv.X() );
-        pos->SetVParameter( uv.Y() );
-      }
-    }
-    if ( uvOK )
-    {
-      n->setXYZ( distXYZ[1], distXYZ[2], distXYZ[3]);
-    }
-    else
+    if ( !UpdatePositionOnSWOL( n, 2*lenDelta, eos, helper ))
     {
       n->setXYZ( oldXYZ.X(), oldXYZ.Y(), oldXYZ.Z() );
       _pos.pop_back();
       Block( eos.GetData() );
       return;
     }
-  }
 
   _len = len;
 
@@ -9697,13 +9999,57 @@ void _LayerEdge::SetNewLength( double len, _EdgesOnShape& eos, SMESH_MesherHelpe
   {
     for ( size_t i = 0; i < _neibors.size(); ++i )
       //if (  _len > _neibors[i]->GetSmooLen() )
-        _neibors[i]->Set( MOVED );
+      _neibors[i]->Set( MOVED );
 
     Set( MOVED );
   }
   dumpMove( n ); //debug
 }
 
+
+//================================================================================
+/*!
+ * \brief Update last position on SWOL by projecting node on SWOL
+*/
+//================================================================================
+
+bool _LayerEdge::UpdatePositionOnSWOL( SMDS_MeshNode*      n,
+                                       double              tol,
+                                       _EdgesOnShape&      eos,
+                                       SMESH_MesherHelper& helper )
+{
+  double distXYZ[4];
+  bool uvOK = false;
+  if ( eos.SWOLType() == TopAbs_EDGE )
+  {
+    double u = Precision::Infinite(); // to force projection w/o distance check
+    uvOK = helper.CheckNodeU( TopoDS::Edge( eos._sWOL ), n, u, tol, /*force=*/true, distXYZ );
+    _pos.back().SetCoord( u, 0, 0 );
+    if ( _nodes.size() > 1 && uvOK )
+    {
+      SMDS_EdgePositionPtr pos = n->GetPosition();
+      pos->SetUParameter( u );
+    }
+  }
+  else //  TopAbs_FACE
+  {
+    gp_XY uv( Precision::Infinite(), 0 );
+    uvOK = helper.CheckNodeUV( TopoDS::Face( eos._sWOL ), n, uv, tol, /*force=*/true, distXYZ );
+    _pos.back().SetCoord( uv.X(), uv.Y(), 0 );
+    if ( _nodes.size() > 1 && uvOK )
+    {
+      SMDS_FacePositionPtr pos = n->GetPosition();
+      pos->SetUParameter( uv.X() );
+      pos->SetVParameter( uv.Y() );
+    }
+  }
+  if ( uvOK )
+  {
+    n->setXYZ( distXYZ[1], distXYZ[2], distXYZ[3]);
+  }
+  return uvOK;
+}
+
 //================================================================================
 /*!
  * \brief Set BLOCKED flag and propagate limited _maxLen to _neibors
@@ -10120,11 +10466,16 @@ bool _ViscousBuilder::refine(_SolidData& data)
             segLen[j] = segLen[j-1] + (edge._pos[j-1] - edge._pos[j] ).Modulus();
         }
       }
-      else if ( !surface.IsNull() ) // SWOL surface with singularities
+      else // SWOL is surface with singularities or irregularly parametrized curve
       {
         pos3D.resize( edge._pos.size() );
-        for ( size_t j = 0; j < edge._pos.size(); ++j )
-          pos3D[j] = surface->Value( edge._pos[j].X(), edge._pos[j].Y() ).XYZ();
+
+        if ( !surface.IsNull() )
+          for ( size_t j = 0; j < edge._pos.size(); ++j )
+            pos3D[j] = surface->Value( edge._pos[j].X(), edge._pos[j].Y() ).XYZ();
+        else if ( !curve.IsNull() )
+          for ( size_t j = 0; j < edge._pos.size(); ++j )
+            pos3D[j] = curve->Value( edge._pos[j].X() ).XYZ();
 
         for ( size_t j = 1; j < edge._pos.size(); ++j )
           segLen[j] = segLen[j-1] + ( pos3D[j-1] - pos3D[j] ).Modulus();
@@ -10156,7 +10507,8 @@ bool _ViscousBuilder::refine(_SolidData& data)
       if ( n2eMap && (( n2e = n2eMap->find( edge._nodes[0] )) != n2eMap->end() ))
       {
         edgeOnSameNode = n2e->second;
-        useExistingPos = ( edgeOnSameNode->_len < edge._len );
+        useExistingPos = ( edgeOnSameNode->_len < edge._len ||
+                           segLen[0] == segLen.back() ); // too short inflation step (bos #20643)
         const gp_XYZ& otherTgtPos = edgeOnSameNode->_pos.back();
         SMDS_PositionPtr  lastPos = tgtNode->GetPosition();
         if ( isOnEdge )
@@ -10171,26 +10523,16 @@ bool _ViscousBuilder::refine(_SolidData& data)
           fpos->SetVParameter( otherTgtPos.Y() );
         }
       }
-      // calculate height of the first layer
-      double h0;
-      const double T = segLen.back(); //data._hyp.GetTotalThickness();
-      const double f = eos._hyp.GetStretchFactor();
-      const int    N = eos._hyp.GetNumberLayers();
-      const double fPowN = pow( f, N );
-      if ( fPowN - 1 <= numeric_limits<double>::min() )
-        h0 = T / N;
-      else
-        h0 = T * ( f - 1 )/( fPowN - 1 );
-
-      const double zeroLen = std::numeric_limits<double>::min();
 
       // create intermediate nodes
-      double hSum = 0, hi = h0/f;
+      const double      h0 = eos._hyp.Get1stLayerThickness( segLen.back() );
+      const double zeroLen = std::numeric_limits<double>::min();
+      double hSum = 0, hi = h0/eos._hyp.GetStretchFactor();
       size_t iSeg = 1;
       for ( size_t iStep = 1; iStep < edge._nodes.size(); ++iStep )
       {
         // compute an intermediate position
-        hi *= f;
+        hi *= eos._hyp.GetStretchFactor();
         hSum += hi;
         while ( hSum > segLen[iSeg] && iSeg < segLen.size()-1 )
           ++iSeg;
@@ -10509,12 +10851,20 @@ namespace VISCOUS_3D
       std::vector< SMESH_NodeXYZ > _nodes;
       TopAbs_ShapeEnum             _vertSWOLType[2]; // shrink part includes VERTEXes
       AverageHyp*                  _vertHyp[2];
+      double                       _edgeWOLLen[2]; // length of wol EDGE
+      double                       _tol; // to compare _edgeWOLLen's
 
       BndPart():
         _isShrink(0), _isReverse(0), _nbSegments(0), _hyp(0),
-        _vertSWOLType{ TopAbs_WIRE, TopAbs_WIRE }, _vertHyp{ 0, 0 }
+        _vertSWOLType{ TopAbs_WIRE, TopAbs_WIRE }, _vertHyp{ 0, 0 }, _edgeWOLLen{ 0., 0.}
       {}
 
+      bool IsEqualLengthEWOL( const BndPart& other ) const
+      {
+        return ( std::abs( _edgeWOLLen[0] - other._edgeWOLLen[0] ) < _tol &&
+                 std::abs( _edgeWOLLen[1] - other._edgeWOLLen[1] ) < _tol );
+      }
+
       bool operator==( const BndPart& other ) const
       {
         return ( _isShrink       == other._isShrink &&
@@ -10525,7 +10875,8 @@ namespace VISCOUS_3D
                  (( !_isShrink ) ||
                   ( *_hyp        == *other._hyp &&
                     vertHyp1()   == other.vertHyp1() &&
-                    vertHyp2()   == other.vertHyp2() ))
+                    vertHyp2()   == other.vertHyp2() &&
+                    IsEqualLengthEWOL( other )))
                  );
       }
       bool CanAppend( const BndPart& other )
@@ -10543,10 +10894,12 @@ namespace VISCOUS_3D
         bool hasCommonNode = ( _nodes.back()->GetID() == other._nodes.front()->GetID() );
         _nodes.insert( _nodes.end(), other._nodes.begin() + hasCommonNode, other._nodes.end() );
         _vertSWOLType[1] = other._vertSWOLType[1];
-        if ( _isShrink )
-          _vertHyp[1] = other._vertHyp[1];
+        if ( _isShrink ) {
+          _vertHyp[1]    = other._vertHyp[1];
+          _edgeWOLLen[1] = other._edgeWOLLen[1];
+        }
       }
-      const SMDS_MeshNode*    Node(size_t i)  const
+      const SMDS_MeshNode* Node(size_t i)  const
       {
         return _nodes[ _isReverse ? ( _nodes.size() - 1 - i ) : i ]._node;
       }
@@ -10561,14 +10914,13 @@ namespace VISCOUS_3D
     SMESH_subMesh*       _subMesh;
     _SolidData*          _data1;
     _SolidData*          _data2;
-    //bool                 _isPeriodic;
 
     std::list< BndPart > _boundary;
     int                  _boundarySize, _nbBoundaryParts;
 
     void Init( SMESH_subMesh* sm, _SolidData* sd1, _SolidData* sd2 )
     {
-      _subMesh = sm; _data1 = sd1; _data2 = sd2; //_isPeriodic = false;
+      _subMesh = sm; _data1 = sd1; _data2 = sd2;
     }
     bool IsSame( const TopoDS_Face& face ) const
     {
@@ -10631,11 +10983,15 @@ namespace VISCOUS_3D
         if ( !periodic._trsf.Solve( srcPnts, tgtPnts )) {
           continue;
         }
-        double tol = std::numeric_limits<double>::max();
+        double tol = std::numeric_limits<double>::max(); // tolerance by segment size
         for ( size_t i = 1; i < srcPnts.size(); ++i ) {
           tol = Min( tol, ( srcPnts[i-1] - srcPnts[i] ).SquareModulus() );
         }
         tol = 0.01 * Sqrt( tol );
+        for ( BndPart& boundary : _boundary ) { // tolerance by VL thickness
+          if ( boundary._isShrink )
+            tol = Min( tol, boundary._hyp->Get1stLayerThickness() / 50. );
+        }
         bool nodeCoincide = true;
         TNodeNodeMap::iterator n2n = periodic._nnMap.begin();
         for ( ; n2n != periodic._nnMap.end() &&  nodeCoincide; ++n2n )
@@ -10643,7 +10999,7 @@ namespace VISCOUS_3D
           SMESH_NodeXYZ nSrc = n2n->first;
           SMESH_NodeXYZ nTgt = n2n->second;
           gp_XYZ pTgt = periodic._trsf.Transform( nSrc );
-          nodeCoincide = (( pTgt - nTgt ).SquareModulus() < tol );
+          nodeCoincide = (( pTgt - nTgt ).SquareModulus() < tol * tol );
         }
         if ( nodeCoincide )
           return true;
@@ -10691,6 +11047,11 @@ namespace VISCOUS_3D
       for ( int iE = 0; iE < nbEdgesInWire.front(); ++iE )
       {
         BndPart bndPart;
+
+        std::vector<const SMDS_MeshNode*> nodes = fSide.GetOrderedNodes( iE );
+        bndPart._nodes.assign( nodes.begin(), nodes.end() );
+        bndPart._nbSegments = bndPart._nodes.size() - 1;
+
         _EdgesOnShape*  eos = _data1->GetShapeEdges( fSide.EdgeID( iE ));
 
         bndPart._isShrink = ( eos->SWOLType() == TopAbs_FACE );
@@ -10719,10 +11080,14 @@ namespace VISCOUS_3D
                 bndPart._vertSWOLType[iV] = eov[iV]->SWOLType();
             }
           }
+          bndPart._edgeWOLLen[0] = fSide.EdgeLength( iE - 1 );
+          bndPart._edgeWOLLen[1] = fSide.EdgeLength( iE + 1 );
+
+          bndPart._tol = std::numeric_limits<double>::max(); // tolerance by segment size
+          for ( size_t i = 1; i < bndPart._nodes.size(); ++i )
+            bndPart._tol = Min( bndPart._tol,
+                                ( bndPart._nodes[i-1] - bndPart._nodes[i] ).SquareModulus() );
         }
-        std::vector<const SMDS_MeshNode*> nodes = fSide.GetOrderedNodes( iE );
-        bndPart._nodes.assign( nodes.begin(), nodes.end() );
-        bndPart._nbSegments = bndPart._nodes.size() - 1;
 
         if ( _boundary.empty() || ! _boundary.back().CanAppend( bndPart ))
           _boundary.push_back( bndPart );
@@ -10829,6 +11194,9 @@ namespace VISCOUS_3D
     }
     SMESHDS_Mesh* meshDS = dataSrc->GetHelper().GetMeshDS();
 
+    dumpFunction(SMESH_Comment("periodicMoveNodes_F")
+                               << _shriFace[iSrc]->_subMesh->GetId() << "_F"
+                               << _shriFace[iTgt]->_subMesh->GetId() );
     TNode2Edge::iterator n2e;
     TNodeNodeMap::iterator n2n = _nnMap.begin();
     for ( ; n2n != _nnMap.end(); ++n2n )
@@ -10858,6 +11226,8 @@ namespace VISCOUS_3D
           SMESH_NodeXYZ pSrc = leSrc->_nodes[ iN ];
           gp_XYZ pTgt = trsf->Transform( pSrc );
           meshDS->MoveNode( leTgt->_nodes[ iN ], pTgt.X(), pTgt.Y(), pTgt.Z() );
+
+          dumpMove( leTgt->_nodes[ iN ]);
         }
       }
     }
@@ -10866,6 +11236,7 @@ namespace VISCOUS_3D
               << _shriFace[iSrc]->_subMesh->GetId() << " -> "
               << _shriFace[iTgt]->_subMesh->GetId() << " -- "
               << ( done ? "DONE" : "FAIL"));
+    dumpFunctionEnd();
 
     return done;
   }
@@ -11400,6 +11771,8 @@ bool _ViscousBuilder::shrink(_SolidData& theData)
       {
         _EdgesOnShape& eos = * subEOS[ iS ];
         if ( eos.ShapeType() != TopAbs_EDGE ) continue;
+        if ( eos.size() == 0 )
+          continue;
 
         const TopoDS_Edge& E = TopoDS::Edge( eos._shape );
         data.SortOnEdge( E, eos._edges );
@@ -11422,6 +11795,8 @@ bool _ViscousBuilder::shrink(_SolidData& theData)
           uvPtVec[ i ].param = helper.GetNodeU( E, edges[i]->_nodes[0] );
           uvPtVec[ i ].SetUV( helper.GetNodeUV( F, edges[i]->_nodes.back() ));
         }
+        // if ( edges.empty() )
+        //   continue;
         BRep_Tool::Range( E, uvPtVec[0].param, uvPtVec.back().param );
         StdMeshers_FaceSide fSide( uvPtVec, F, E, _mesh );
         StdMeshers_ViscousLayers2D::SetProxyMeshOfEdge( fSide );
@@ -11569,7 +11944,8 @@ bool _ViscousBuilder::prepareEdgeToShrink( _LayerEdge&            edge,
     if ( !n2 )
       return error(SMESH_Comment("Wrongly meshed EDGE ") << getMeshDS()->ShapeToIndex( E ));
 
-    if ( n2 == tgtNode ) // for 3D_mesh_GHS3D_01/B1
+    if ( n2 == tgtNode       || // for 3D_mesh_GHS3D_01/B1
+         n2 == edge._nodes[1] ) // bos #20643
     {
       // shrunk by other SOLID
       edge.Set( _LayerEdge::SHRUNK ); // ???
@@ -11804,7 +12180,7 @@ void _ViscousBuilder::fixBadFaces(const TopoDS_Face&          F,
  */
 //================================================================================
 
-bool _LayerEdge::SetNewLength2d( Handle(Geom_Surface)& /*surface*/,
+bool _LayerEdge::SetNewLength2d( Handle(Geom_Surface)& surface,
                                  const TopoDS_Face&    F,
                                  _EdgesOnShape&        eos,
                                  SMESH_MesherHelper&   helper )
@@ -11831,8 +12207,8 @@ bool _LayerEdge::SetNewLength2d( Handle(Geom_Surface)& /*surface*/,
         continue; // simplex of quadrangle created by addBoundaryElements()
 
       // find intersection of 2 lines: curUV-tgtUV and that connecting simplex nodes
-      gp_XY uvN1 = helper.GetNodeUV( F, _simplices[i]._nPrev );
-      gp_XY uvN2 = helper.GetNodeUV( F, _simplices[i]._nNext );
+      gp_XY uvN1 = helper.GetNodeUV( F, _simplices[i]._nPrev, tgtNode );
+      gp_XY uvN2 = helper.GetNodeUV( F, _simplices[i]._nNext, tgtNode );
       gp_XY dirN = uvN2 - uvN1;
       double det = uvDir.Crossed( dirN );
       if ( Abs( det )  < std::numeric_limits<double>::min() ) continue;
@@ -11864,6 +12240,8 @@ bool _LayerEdge::SetNewLength2d( Handle(Geom_Surface)& /*surface*/,
     gp_Pnt p = surface->Value( newUV.X(), newUV.Y() );
     tgtNode->setXYZ( p.X(), p.Y(), p.Z() );
     dumpMove( tgtNode );
+#else
+    if ( surface.IsNull() ) {}
 #endif
   }
   else // _sWOL is TopAbs_EDGE
@@ -12099,11 +12477,18 @@ void _Shrinker1D::AddEdge( const _LayerEdge*   e,
   double u = helper.GetNodeU( _geomEdge, e->_nodes[0], e->_nodes.back());
   _edges[ u < 0.5*(f+l) ? 0 : 1 ] = e;
 
-  // Update _nodes
+  // Check if the nodes are already shrunk by another SOLID
 
   const SMDS_MeshNode* tgtNode0 = TgtNode( 0 );
   const SMDS_MeshNode* tgtNode1 = TgtNode( 1 );
 
+  _done = (( tgtNode0 && tgtNode0->NbInverseElements( SMDSAbs_Edge ) == 2 ) ||
+           ( tgtNode1 && tgtNode1->NbInverseElements( SMDSAbs_Edge ) == 2 ));
+  if ( _done )
+    _nodes.resize( 1, nullptr );
+
+  // Update _nodes
+
   if ( _nodes.empty() )
   {
     SMESHDS_SubMesh * eSubMesh = helper.GetMeshDS()->MeshElements( _geomEdge );
@@ -12172,6 +12557,8 @@ void _Shrinker1D::Compute(bool set3D, SMESH_MesherHelper& helper)
   double f,l;
   if ( set3D || _done )
   {
+    dumpFunction(SMESH_Comment("shrink1D_E") << helper.GetMeshDS()->ShapeToIndex( _geomEdge )<<
+                 "_F" << helper.GetSubShapeID() );
     Handle(Geom_Curve) C = BRep_Tool::Curve(_geomEdge, f,l);
     GeomAdaptor_Curve aCurve(C, f,l);
 
@@ -12193,7 +12580,9 @@ void _Shrinker1D::Compute(bool set3D, SMESH_MesherHelper& helper)
       pos->SetUParameter( u );
       gp_Pnt p = C->Value( u );
       const_cast< SMDS_MeshNode*>( _nodes[i] )->setXYZ( p.X(), p.Y(), p.Z() );
+      dumpMove( _nodes[i] );
     }
+    dumpFunctionEnd();
   }
   else
   {
@@ -12266,6 +12655,140 @@ void _Shrinker1D::SwapSrcTgtNodes( SMESHDS_Mesh* mesh )
   }
 }
 
+//================================================================================
+/*!
+ * \brief Setup quadPoints
+ */
+//================================================================================
+
+_Mapper2D::_Mapper2D( const TParam2ColumnMap & param2ColumnMap, const TNode2Edge& n2eMap )
+{
+  size_t i, iSize = _quadPoints.iSize = param2ColumnMap.size();
+  size_t j, jSize = _quadPoints.jSize = param2ColumnMap.begin()->second.size();
+  if ( _quadPoints.iSize < 3 ||
+       _quadPoints.jSize < 3 )
+    return;
+  _quadPoints.uv_grid.resize( iSize * jSize );
+
+  // set nodes
+  i = 0;
+  for ( auto & u_columnNodes : param2ColumnMap )
+  {
+    for ( j = 0; j < u_columnNodes.second.size(); ++j )
+      _quadPoints.UVPt( i, j ).node = u_columnNodes.second[ j ];
+    ++i;
+  }
+
+  // compute x parameter on borders
+  uvPnt( 0, 0       ).x = 0;
+  uvPnt( 0, jSize-1 ).x = 0;
+  gp_Pnt p0, pPrev0 = SMESH_NodeXYZ( uvPnt( 0, 0       ).node );
+  gp_Pnt p1, pPrev1 = SMESH_NodeXYZ( uvPnt( 0, jSize-1 ).node );
+  for ( i = 1; i < iSize; ++i )
+  {
+    p0 = SMESH_NodeXYZ( uvPnt( i, 0       ).node );
+    p1 = SMESH_NodeXYZ( uvPnt( i, jSize-1 ).node );
+    uvPnt( i, 0       ).x = uvPnt( i-1, 0       ).x + p0.Distance( pPrev0 );
+    uvPnt( i, jSize-1 ).x = uvPnt( i-1, jSize-1 ).x + p1.Distance( pPrev1 );
+    pPrev0 = p0;
+    pPrev1 = p1;
+  }
+  for ( i = 1; i < iSize-1; ++i )
+  {
+    uvPnt( i, 0       ).x /= uvPnt( iSize-1, 0       ).x;
+    uvPnt( i, jSize-1 ).x /= uvPnt( iSize-1, jSize-1 ).x;
+    uvPnt( i, 0       ).y = 0;
+    uvPnt( i, jSize-1 ).y = 1;
+  }
+
+  // compute y parameter on borders
+  uvPnt( 0,       0 ).y = 0;
+  uvPnt( iSize-1, 0 ).y = 0;
+  pPrev0 = SMESH_NodeXYZ( uvPnt( 0,       0 ).node );
+  pPrev1 = SMESH_NodeXYZ( uvPnt( iSize-1, 0 ).node );
+  for ( j = 1; j < jSize; ++j )
+  {
+    p0 = SMESH_NodeXYZ( uvPnt( 0,       j ).node );
+    p1 = SMESH_NodeXYZ( uvPnt( iSize-1, j ).node );
+    uvPnt( 0,       j ).y = uvPnt( 0,       j-1 ).y + p0.Distance( pPrev0 );
+    uvPnt( iSize-1, j ).y = uvPnt( iSize-1, j-1 ).y + p1.Distance( pPrev1 );
+    pPrev0 = p0;
+    pPrev1 = p1;
+  }
+  for ( j = 1; j < jSize-1; ++j )
+  {
+    uvPnt( 0,       j ).y /= uvPnt( 0,       jSize-1 ).y;
+    uvPnt( iSize-1, j ).y /= uvPnt( iSize-1, jSize-1 ).y;
+    uvPnt( 0,       j ).x = 0;
+    uvPnt( iSize-1, j ).x = 1;
+  }
+
+  // compute xy of internal nodes
+  for ( i = 1; i < iSize-1; ++i )
+  {
+    const double x0 = uvPnt( i, 0       ).x;
+    const double x1 = uvPnt( i, jSize-1 ).x;
+    for ( j = 1; j < jSize-1; ++j )
+    {
+      const double y0 = uvPnt( 0,       j ).y;
+      const double y1 = uvPnt( iSize-1, j ).y;
+      double x = (x0 + y0 * (x1 - x0)) / (1 - (y1 - y0) * (x1 - x0));
+      double y = y0 + x * (y1 - y0);
+      uvPnt( i, j ).x = x;
+      uvPnt( i, j ).y = y;
+    }
+  }
+
+  // replace base nodes with target ones
+  for ( i = 0; i < iSize; ++i )
+    for ( j = 0; j < jSize; ++j )
+    {
+      auto n2e = n2eMap.find( uvPnt( i, j ).node );
+      uvPnt( i, j ).node = n2e->second->_nodes.back();
+    }
+
+  return;
+}
+
+//================================================================================
+/*!
+ * \brief Compute positions of nodes of 2D structured mesh using TFI
+ */
+//================================================================================
+
+bool _Mapper2D::ComputeNodePositions()
+{
+  if ( _quadPoints.uv_grid.empty() )
+    return true;
+
+  size_t i, iSize = _quadPoints.iSize;
+  size_t j, jSize = _quadPoints.jSize;
+
+  SMESH_NodeXYZ a0 ( uvPnt( 0,       0       ).node );
+  SMESH_NodeXYZ a1 ( uvPnt( iSize-1, 0       ).node );
+  SMESH_NodeXYZ a2 ( uvPnt( iSize-1, jSize-1 ).node );
+  SMESH_NodeXYZ a3 ( uvPnt( 0,       jSize-1 ).node );
+
+  for ( i = 1; i < iSize-1; ++i )
+  {
+    SMESH_NodeXYZ p0 ( uvPnt( i, 0       ).node );
+    SMESH_NodeXYZ p2 ( uvPnt( i, jSize-1 ).node );
+    for ( j = 1; j < jSize-1; ++j )
+    {
+      SMESH_NodeXYZ p1 ( uvPnt( iSize-1, j ).node );
+      SMESH_NodeXYZ p3 ( uvPnt( 0,       j ).node );
+      double x = uvPnt( i, j ).x;
+      double y = uvPnt( i, j ).y;
+
+      gp_XYZ p = SMESH_MesherHelper::calcTFI( x, y, a0,a1,a2,a3, p0,p1,p2,p3 );
+      const_cast< SMDS_MeshNode* >( uvPnt( i, j ).node )->setXYZ( p.X(), p.Y(), p.Z() );
+
+      dumpMove( uvPnt( i, j ).node );
+    }
+  }
+  return true;
+}
+
 //================================================================================
 /*!
  * \brief Creates 2D and 1D elements on boundaries of new prisms