diff --git a/CMakeLists.txt b/CMakeLists.txt index b322f2b40..68f91de51 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -27,7 +27,7 @@ INCLUDE(CMakeDependentOption) STRING(TOUPPER ${PROJECT_NAME} PROJECT_NAME_UC) SET(${PROJECT_NAME_UC}_MAJOR_VERSION 9) -SET(${PROJECT_NAME_UC}_MINOR_VERSION 6) +SET(${PROJECT_NAME_UC}_MINOR_VERSION 7) SET(${PROJECT_NAME_UC}_PATCH_VERSION 0) SET(${PROJECT_NAME_UC}_VERSION ${${PROJECT_NAME_UC}_MAJOR_VERSION}.${${PROJECT_NAME_UC}_MINOR_VERSION}.${${PROJECT_NAME_UC}_PATCH_VERSION}) diff --git a/doc/salome/examples/3dmesh.py b/doc/salome/examples/3dmesh.py index 04d6073bd..0fdfcb68d 100644 --- a/doc/salome/examples/3dmesh.py +++ b/doc/salome/examples/3dmesh.py @@ -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() diff --git a/doc/salome/examples/CTestTestfileInstall.cmake b/doc/salome/examples/CTestTestfileInstall.cmake index daf0e0004..cf70be839 100644 --- a/doc/salome/examples/CTestTestfileInstall.cmake +++ b/doc/salome/examples/CTestTestfileInstall.cmake @@ -19,14 +19,14 @@ 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() diff --git a/doc/salome/examples/MGAdaptTests_without_session.py b/doc/salome/examples/MGAdaptTests_without_session.py index 4855345c1..aa3f087a2 100644 --- a/doc/salome/examples/MGAdaptTests_without_session.py +++ b/doc/salome/examples/MGAdaptTests_without_session.py @@ -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 diff --git a/doc/salome/examples/a3DmeshOnModified2Dmesh.py b/doc/salome/examples/a3DmeshOnModified2Dmesh.py index ae03906c8..fb49f873c 100644 --- a/doc/salome/examples/a3DmeshOnModified2Dmesh.py +++ b/doc/salome/examples/a3DmeshOnModified2Dmesh.py @@ -1,5 +1,5 @@ import salome -salome.salome_init() +salome.salome_init_without_session() from salome.geom import geomBuilder geompy = geomBuilder.New() diff --git a/doc/salome/examples/basic_geom_smesh_without_session.py b/doc/salome/examples/basic_geom_smesh_without_session.py index d10a23cee..9626ff9eb 100644 --- a/doc/salome/examples/basic_geom_smesh_without_session.py +++ b/doc/salome/examples/basic_geom_smesh_without_session.py @@ -50,4 +50,13 @@ isDone = Mesh_1.Compute() smesh.SetName(NETGEN_1D_2D_3D.GetAlgorithm(), 'NETGEN 1D-2D-3D') smesh.SetName(Mesh_1.GetMesh(), 'Mesh_1') -assert(Mesh_1.GetMesh().NbTetras()>=5) +nbOfTetraExp = 5 + +assert(Mesh_1.GetMesh().NbTetras()>=nbOfTetraExp) + +#Mesh_1.ExportMED("toto.med") + +import medcoupling as mc + +mv_mm = Mesh_1.ExportMEDCoupling() +assert(mc.MEDCoupling1SGTUMesh(mv_mm[0]).getNumberOfCells()>=nbOfTetraExp) diff --git a/doc/salome/examples/basic_smesh_output_with_mc_field.py b/doc/salome/examples/basic_smesh_output_with_mc_field.py new file mode 100644 index 000000000..f900b96c2 --- /dev/null +++ b/doc/salome/examples/basic_smesh_output_with_mc_field.py @@ -0,0 +1,175 @@ +#!/usr/bin/env python + +import sys +import salome + +import unittest + +class SMESHExportOfFieldsInMemory(unittest.TestCase): + + def testMEDCouplingFieldOnCells(self): + """ + Test focuses on ExportMEDCoupling method in the context of MED_CELL field output. + """ + salome.standalone() + salome.salome_init() + ### + ### SHAPER component + ### + + from salome.shaper import model + + model.begin() + partSet = model.moduleDocument() + + ### Create Part + Part_1 = model.addPart(partSet) + Part_1_doc = Part_1.document() + + ### Create Box + Box_1 = model.addBox(Part_1_doc, 10, 10, 10) + + ### Create Plane + Plane_4 = model.addPlane(Part_1_doc, model.selection("FACE", "PartSet/XOY"), 5, False) + + ### Create Plane + Plane_5 = model.addPlane(Part_1_doc, model.selection("FACE", "PartSet/YOZ"), 5, False) + + ### Create Partition + Partition_1_objects = [model.selection("FACE", "Plane_1"), + model.selection("FACE", "Plane_2"), + model.selection("SOLID", "Box_1_1")] + Partition_1 = model.addPartition(Part_1_doc, Partition_1_objects, keepSubResults = True) + + ### Create Field + Field_1_objects = [model.selection("SOLID", "Partition_1_1_2"), + model.selection("SOLID", "Partition_1_1_4"), + model.selection("SOLID", "Partition_1_1_1"), + model.selection("SOLID", "Partition_1_1_3")] + Field_1 = model.addField(Part_1_doc, 1, "DOUBLE", 1, ["Comp 1"], Field_1_objects) + Field_1.addStep(0, 0, [[0], [1], [2], [3], [4]]) + + + model.end() + + ### + ### SHAPERSTUDY component + ### + + model.publishToShaperStudy() + import SHAPERSTUDY + Partition_1_1, Field_1_1 = SHAPERSTUDY.shape(model.featureStringId(Partition_1)) + ### + ### SMESH component + ### + + import SMESH, SALOMEDS + from salome.smesh import smeshBuilder + + smesh = smeshBuilder.New() + #smesh.SetEnablePublish( False ) # Set to False to avoid publish in study if not needed or in some particular situations: + # multiples meshes built in parallel, complex and numerous mesh edition (performance) + + Mesh_1 = smesh.Mesh(Partition_1_1) + Regular_1D = Mesh_1.Segment() + Local_Length_1 = Regular_1D.LocalLength(5,None,1e-07) + Quadrangle_2D = Mesh_1.Quadrangle(algo=smeshBuilder.QUADRANGLE) + Hexa_3D = Mesh_1.Hexahedron(algo=smeshBuilder.Hexa) + isDone = Mesh_1.Compute() + smesh.SetName(Mesh_1, 'Mesh_1') + + #### Mesh_1.ExportMED( r'Mesh_with_one_field_on_cells.med', 0, 41, 1, Mesh_1.GetMesh(), 1, [ Field_1_1 ], '',-1 ) + mfd = Mesh_1.ExportMEDCoupling(0, Mesh_1.GetMesh(), 1, [ Field_1_1 ], '',-1 )#### <- important line of test is here ! + + self.assertEqual(len(mfd.getMeshes()),1) + self.assertEqual(len(mfd.getFields()),1) + f = mfd.getFields()[0][0].field(mfd.getMeshes()[0]) + f.checkConsistencyLight() + import medcoupling + self.assertEqual(f.getDiscretization().getEnum(),medcoupling.ON_CELLS) + self.assertTrue(f.getMesh().getNumberOfCells()>1) + pass + + + def testMEDCouplingFieldOnNodes(self): + """ + Test focuses on ExportMEDCoupling method in the context of MED_NODES field output. + """ + salome.standalone() + salome.salome_init() + + ### + ### SHAPER component + ### + + from salome.shaper import model + + model.begin() + partSet = model.moduleDocument() + + ### Create Part + Part_1 = model.addPart(partSet) + Part_1_doc = Part_1.document() + + ### Create Box + Box_1 = model.addBox(Part_1_doc, 10, 10, 10) + + ### Create Plane + Plane_4 = model.addPlane(Part_1_doc, model.selection("FACE", "PartSet/XOY"), 5, False) + + ### Create Plane + Plane_5 = model.addPlane(Part_1_doc, model.selection("FACE", "PartSet/YOZ"), 5, False) + + ### Create Partition + Partition_1_objects = [model.selection("FACE", "Plane_1"), + model.selection("FACE", "Plane_2"), + model.selection("SOLID", "Box_1_1")] + Partition_1 = model.addPartition(Part_1_doc, Partition_1_objects, keepSubResults = True) + + ### Create Field + Field_2_objects = [model.selection("VERTEX", "[Partition_1_1_2/Modified_Face&Box_1_1/Back][Partition_1_1_2/Modified_Face&Box_1_1/Left][Partition_1_1_2/Modified_Face&Box_1_1/Top]"), + model.selection("VERTEX", "Partition_1_1_2/Generated_Vertex&Plane_2/Plane_2&new_weak_name_1"), + model.selection("VERTEX", "[Partition_1_1_4/Modified_Face&Box_1_1/Front][Partition_1_1_4/Modified_Face&Box_1_1/Left][Partition_1_1_4/Modified_Face&Box_1_1/Top]"), + model.selection("VERTEX", "Partition_1_1_1/Generated_Vertex&Plane_1/Plane_1&new_weak_name_1"), + model.selection("VERTEX", "[Partition_1_1_1/Modified_Face&Box_1_1/Left][Partition_1_1_1/Modified_Face&Plane_1/Plane_1][Partition_1_1_1/Modified_Face&Plane_2/Plane_2]"), + model.selection("VERTEX", "Partition_1_1_3/Generated_Vertex&Plane_1/Plane_1&new_weak_name_1"), + model.selection("VERTEX", "[Partition_1_1_1/Modified_Face&Box_1_1/Back][Partition_1_1_1/Modified_Face&Box_1_1/Left][Partition_1_1_1/Modified_Face&Box_1_1/Bottom]"), + model.selection("VERTEX", "Partition_1_1_1/Generated_Vertex&Plane_2/Plane_2&new_weak_name_1"), + model.selection("VERTEX", "[Partition_1_1_3/Modified_Face&Box_1_1/Left][Partition_1_1_3/Modified_Face&Box_1_1/Bottom][Partition_1_1_3/Modified_Face&Box_1_1/Front]")] + Field_2 = model.addField(Part_1_doc, 1, "DOUBLE", 1, ["Comp 1"], Field_2_objects) + Field_2.addStep(0, 0, [[0], [1], [2], [3], [4], [5], [6], [7], [8], [9]]) + + model.end() + + ### + ### SHAPERSTUDY component + ### + + model.publishToShaperStudy() + import SHAPERSTUDY + Partition_1_1, Field_2_1 = SHAPERSTUDY.shape(model.featureStringId(Partition_1)) + ### + ### SMESH component + ### + + import SMESH, SALOMEDS + from salome.smesh import smeshBuilder + + smesh = smeshBuilder.New() + #smesh.SetEnablePublish( False ) # Set to False to avoid publish in study if not needed or in some particular situations: + # multiples meshes built in parallel, complex and numerous mesh edition (performance) + + Mesh_1 = smesh.Mesh(Partition_1_1) + Regular_1D = Mesh_1.Segment() + Local_Length_1 = Regular_1D.LocalLength(5,None,1e-07) + Quadrangle_2D = Mesh_1.Quadrangle(algo=smeshBuilder.QUADRANGLE) + Hexa_3D = Mesh_1.Hexahedron(algo=smeshBuilder.Hexa) + isDone = Mesh_1.Compute() + smesh.SetName(Mesh_1, 'Mesh_1') + + # 23th of june 2021 : Bug both in ExportMED and in ExportMEDCoupling + #Mesh_1.ExportMED( r'/tmp/Mesh_with_one_field_on_nodes.med', 0, 41, 1, Mesh_1.GetMesh(), 1, [ Field_2_1 ], '',-1 ) + #mfd = Mesh_1.ExportMEDCoupling(0,Mesh_1.GetMesh(), 1, [ Field_2_1 ], '',-1) + +if __name__ == '__main__': + unittest.main() diff --git a/doc/salome/examples/blocFissure_01_without_session.py b/doc/salome/examples/blocFissure_01_without_session.py old mode 100755 new mode 100644 index fcdda3284..14c186f72 --- a/doc/salome/examples/blocFissure_01_without_session.py +++ b/doc/salome/examples/blocFissure_01_without_session.py @@ -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"]) diff --git a/doc/salome/examples/blocFissure_02_without_session.py b/doc/salome/examples/blocFissure_02_without_session.py old mode 100755 new mode 100644 index 72700e3e9..49e0e8398 --- a/doc/salome/examples/blocFissure_02_without_session.py +++ b/doc/salome/examples/blocFissure_02_without_session.py @@ -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"]) diff --git a/doc/salome/examples/blocFissure_03_without_session.py b/doc/salome/examples/blocFissure_03_without_session.py old mode 100755 new mode 100644 index a6f730c21..2b2f8ad46 --- a/doc/salome/examples/blocFissure_03_without_session.py +++ b/doc/salome/examples/blocFissure_03_without_session.py @@ -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"]) diff --git a/doc/salome/examples/blocFissure_04_without_session.py b/doc/salome/examples/blocFissure_04_without_session.py old mode 100755 new mode 100644 index e535f7632..0474743e7 --- a/doc/salome/examples/blocFissure_04_without_session.py +++ b/doc/salome/examples/blocFissure_04_without_session.py @@ -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"]) diff --git a/doc/salome/examples/blocFissure_05_without_session.py b/doc/salome/examples/blocFissure_05_without_session.py old mode 100755 new mode 100644 index 16e4bb331..b86a2ee02 --- a/doc/salome/examples/blocFissure_05_without_session.py +++ b/doc/salome/examples/blocFissure_05_without_session.py @@ -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"]) diff --git a/doc/salome/examples/blocFissure_06_without_session.py b/doc/salome/examples/blocFissure_06_without_session.py old mode 100755 new mode 100644 index 185f5d74f..fd2ef82fc --- a/doc/salome/examples/blocFissure_06_without_session.py +++ b/doc/salome/examples/blocFissure_06_without_session.py @@ -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"]) diff --git a/doc/salome/examples/blocFissure_07_without_session.py b/doc/salome/examples/blocFissure_07_without_session.py old mode 100755 new mode 100644 index 87ff9823b..d4d383656 --- a/doc/salome/examples/blocFissure_07_without_session.py +++ b/doc/salome/examples/blocFissure_07_without_session.py @@ -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"]) diff --git a/doc/salome/examples/cartesian_algo.py b/doc/salome/examples/cartesian_algo.py index d7d64b8b7..da86cf423 100644 --- a/doc/salome/examples/cartesian_algo.py +++ b/doc/salome/examples/cartesian_algo.py @@ -2,7 +2,7 @@ import salome -salome.salome_init() +salome.salome_init_without_session() import GEOM from salome.geom import geomBuilder geompy = geomBuilder.New() diff --git a/doc/salome/examples/create_penta_biquad.py b/doc/salome/examples/create_penta_biquad.py index 9e7ec271a..c13f25c38 100644 --- a/doc/salome/examples/create_penta_biquad.py +++ b/doc/salome/examples/create_penta_biquad.py @@ -3,7 +3,7 @@ import sys import salome -salome.salome_init() +salome.salome_init_without_session() import SMESH, SALOMEDS from salome.smesh import smeshBuilder diff --git a/doc/salome/examples/creating_meshes_ex01.py b/doc/salome/examples/creating_meshes_ex01.py index 110f6269a..ba8563d6d 100644 --- a/doc/salome/examples/creating_meshes_ex01.py +++ b/doc/salome/examples/creating_meshes_ex01.py @@ -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() diff --git a/doc/salome/examples/creating_meshes_ex02.py b/doc/salome/examples/creating_meshes_ex02.py index 522f72bf4..8a8966a3f 100644 --- a/doc/salome/examples/creating_meshes_ex02.py +++ b/doc/salome/examples/creating_meshes_ex02.py @@ -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() diff --git a/doc/salome/examples/creating_meshes_ex03.py b/doc/salome/examples/creating_meshes_ex03.py index 42bf8c91a..fc20d3660 100644 --- a/doc/salome/examples/creating_meshes_ex03.py +++ b/doc/salome/examples/creating_meshes_ex03.py @@ -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() diff --git a/doc/salome/examples/creating_meshes_ex04.py b/doc/salome/examples/creating_meshes_ex04.py index 0a3cc9faf..7101a0226 100644 --- a/doc/salome/examples/creating_meshes_ex04.py +++ b/doc/salome/examples/creating_meshes_ex04.py @@ -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() diff --git a/doc/salome/examples/creating_meshes_ex05.py b/doc/salome/examples/creating_meshes_ex05.py index 08e8d135f..725c7e953 100644 --- a/doc/salome/examples/creating_meshes_ex05.py +++ b/doc/salome/examples/creating_meshes_ex05.py @@ -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() diff --git a/doc/salome/examples/creating_meshes_ex06.py b/doc/salome/examples/creating_meshes_ex06.py index 20b8a0434..60360e14b 100644 --- a/doc/salome/examples/creating_meshes_ex06.py +++ b/doc/salome/examples/creating_meshes_ex06.py @@ -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() diff --git a/doc/salome/examples/creating_meshes_ex07.py b/doc/salome/examples/creating_meshes_ex07.py index 669c9b088..f18109cda 100644 --- a/doc/salome/examples/creating_meshes_ex07.py +++ b/doc/salome/examples/creating_meshes_ex07.py @@ -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 diff --git a/doc/salome/examples/creating_meshes_ex08.py b/doc/salome/examples/creating_meshes_ex08.py index ff41f09c6..2f506fa2b 100644 --- a/doc/salome/examples/creating_meshes_ex08.py +++ b/doc/salome/examples/creating_meshes_ex08.py @@ -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() diff --git a/doc/salome/examples/defining_hypotheses_adaptive1d.py b/doc/salome/examples/defining_hypotheses_adaptive1d.py index 579d14de5..48d927daa 100644 --- a/doc/salome/examples/defining_hypotheses_adaptive1d.py +++ b/doc/salome/examples/defining_hypotheses_adaptive1d.py @@ -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 diff --git a/doc/salome/examples/defining_hypotheses_ex01.py b/doc/salome/examples/defining_hypotheses_ex01.py index a4083ba49..0a2401d52 100644 --- a/doc/salome/examples/defining_hypotheses_ex01.py +++ b/doc/salome/examples/defining_hypotheses_ex01.py @@ -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() diff --git a/doc/salome/examples/defining_hypotheses_ex02.py b/doc/salome/examples/defining_hypotheses_ex02.py index 9473354b3..c5a5ce205 100644 --- a/doc/salome/examples/defining_hypotheses_ex02.py +++ b/doc/salome/examples/defining_hypotheses_ex02.py @@ -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() diff --git a/doc/salome/examples/defining_hypotheses_ex03.py b/doc/salome/examples/defining_hypotheses_ex03.py index 3e0a5a7de..14af89e19 100644 --- a/doc/salome/examples/defining_hypotheses_ex03.py +++ b/doc/salome/examples/defining_hypotheses_ex03.py @@ -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() diff --git a/doc/salome/examples/defining_hypotheses_ex04.py b/doc/salome/examples/defining_hypotheses_ex04.py index c15e4421b..bb38eeb9d 100644 --- a/doc/salome/examples/defining_hypotheses_ex04.py +++ b/doc/salome/examples/defining_hypotheses_ex04.py @@ -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() diff --git a/doc/salome/examples/defining_hypotheses_ex05.py b/doc/salome/examples/defining_hypotheses_ex05.py index d99844718..25fe5429f 100644 --- a/doc/salome/examples/defining_hypotheses_ex05.py +++ b/doc/salome/examples/defining_hypotheses_ex05.py @@ -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() diff --git a/doc/salome/examples/defining_hypotheses_ex06.py b/doc/salome/examples/defining_hypotheses_ex06.py index f0a02aee4..687de13f7 100644 --- a/doc/salome/examples/defining_hypotheses_ex06.py +++ b/doc/salome/examples/defining_hypotheses_ex06.py @@ -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() diff --git a/doc/salome/examples/defining_hypotheses_ex07.py b/doc/salome/examples/defining_hypotheses_ex07.py index a8a8e9fd2..2beb838d2 100644 --- a/doc/salome/examples/defining_hypotheses_ex07.py +++ b/doc/salome/examples/defining_hypotheses_ex07.py @@ -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() diff --git a/doc/salome/examples/defining_hypotheses_ex08.py b/doc/salome/examples/defining_hypotheses_ex08.py index 285eae2ad..ee0af3912 100644 --- a/doc/salome/examples/defining_hypotheses_ex08.py +++ b/doc/salome/examples/defining_hypotheses_ex08.py @@ -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() diff --git a/doc/salome/examples/defining_hypotheses_ex09.py b/doc/salome/examples/defining_hypotheses_ex09.py index 6e86cc95e..7ac2a0fb4 100644 --- a/doc/salome/examples/defining_hypotheses_ex09.py +++ b/doc/salome/examples/defining_hypotheses_ex09.py @@ -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() diff --git a/doc/salome/examples/defining_hypotheses_ex10.py b/doc/salome/examples/defining_hypotheses_ex10.py index c55af79df..0801c2cfc 100644 --- a/doc/salome/examples/defining_hypotheses_ex10.py +++ b/doc/salome/examples/defining_hypotheses_ex10.py @@ -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() diff --git a/doc/salome/examples/defining_hypotheses_ex11.py b/doc/salome/examples/defining_hypotheses_ex11.py index a57d0781d..5e85222ad 100644 --- a/doc/salome/examples/defining_hypotheses_ex11.py +++ b/doc/salome/examples/defining_hypotheses_ex11.py @@ -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() diff --git a/doc/salome/examples/defining_hypotheses_ex12.py b/doc/salome/examples/defining_hypotheses_ex12.py index 7ead18cbf..9db644836 100644 --- a/doc/salome/examples/defining_hypotheses_ex12.py +++ b/doc/salome/examples/defining_hypotheses_ex12.py @@ -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() diff --git a/doc/salome/examples/defining_hypotheses_ex13.py b/doc/salome/examples/defining_hypotheses_ex13.py index e95246001..c7c736cff 100644 --- a/doc/salome/examples/defining_hypotheses_ex13.py +++ b/doc/salome/examples/defining_hypotheses_ex13.py @@ -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() diff --git a/doc/salome/examples/defining_hypotheses_ex14.py b/doc/salome/examples/defining_hypotheses_ex14.py index d33e1e155..f1e7e39f3 100644 --- a/doc/salome/examples/defining_hypotheses_ex14.py +++ b/doc/salome/examples/defining_hypotheses_ex14.py @@ -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() diff --git a/doc/salome/examples/defining_hypotheses_ex15.py b/doc/salome/examples/defining_hypotheses_ex15.py index 5a32a1da5..7b0cfbaa4 100644 --- a/doc/salome/examples/defining_hypotheses_ex15.py +++ b/doc/salome/examples/defining_hypotheses_ex15.py @@ -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 diff --git a/doc/salome/examples/defining_hypotheses_ex16.py b/doc/salome/examples/defining_hypotheses_ex16.py index 575601f1e..2826aa15e 100644 --- a/doc/salome/examples/defining_hypotheses_ex16.py +++ b/doc/salome/examples/defining_hypotheses_ex16.py @@ -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() diff --git a/doc/salome/examples/defining_hypotheses_ex17.py b/doc/salome/examples/defining_hypotheses_ex17.py index cadd71e24..da76f2210 100644 --- a/doc/salome/examples/defining_hypotheses_ex17.py +++ b/doc/salome/examples/defining_hypotheses_ex17.py @@ -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() diff --git a/doc/salome/examples/defining_hypotheses_len_near_vertex.py b/doc/salome/examples/defining_hypotheses_len_near_vertex.py index 6d8ab44b2..62379eb8e 100644 --- a/doc/salome/examples/defining_hypotheses_len_near_vertex.py +++ b/doc/salome/examples/defining_hypotheses_len_near_vertex.py @@ -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 diff --git a/doc/salome/examples/extrusion_penta_biquad.py b/doc/salome/examples/extrusion_penta_biquad.py index b98f8cd4b..fb50008a9 100644 --- a/doc/salome/examples/extrusion_penta_biquad.py +++ b/doc/salome/examples/extrusion_penta_biquad.py @@ -3,7 +3,7 @@ import sys import salome -salome.salome_init() +salome.salome_init_without_session() import GEOM from salome.geom import geomBuilder diff --git a/doc/salome/examples/filters_ex09.py b/doc/salome/examples/filters_ex09.py index 21c1d6c94..8e2ebfd3d 100644 --- a/doc/salome/examples/filters_ex09.py +++ b/doc/salome/examples/filters_ex09.py @@ -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 diff --git a/doc/salome/examples/filters_ex10.py b/doc/salome/examples/filters_ex10.py index d1f5023eb..b90e5188f 100644 --- a/doc/salome/examples/filters_ex10.py +++ b/doc/salome/examples/filters_ex10.py @@ -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 diff --git a/doc/salome/examples/filters_ex16.py b/doc/salome/examples/filters_ex16.py index e417ca2fa..4e3d27be4 100644 --- a/doc/salome/examples/filters_ex16.py +++ b/doc/salome/examples/filters_ex16.py @@ -2,7 +2,7 @@ import salome -salome.salome_init() +salome.salome_init_without_session() import GEOM from salome.geom import geomBuilder geompy = geomBuilder.New() diff --git a/doc/salome/examples/filters_ex17.py b/doc/salome/examples/filters_ex17.py index a05fbaa21..83eda322c 100644 --- a/doc/salome/examples/filters_ex17.py +++ b/doc/salome/examples/filters_ex17.py @@ -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 diff --git a/doc/salome/examples/filters_ex18.py b/doc/salome/examples/filters_ex18.py index 6fcba2650..c4ec48107 100644 --- a/doc/salome/examples/filters_ex18.py +++ b/doc/salome/examples/filters_ex18.py @@ -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 diff --git a/doc/salome/examples/filters_ex39.py b/doc/salome/examples/filters_ex39.py index 6a2ddd507..52de1c3d7 100644 --- a/doc/salome/examples/filters_ex39.py +++ b/doc/salome/examples/filters_ex39.py @@ -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 index 000000000..df8dd13f4 --- /dev/null +++ b/doc/salome/examples/find_salome_actor_delegate_to_vtk.py @@ -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!') diff --git a/doc/salome/examples/generate_flat_elements.py b/doc/salome/examples/generate_flat_elements.py index 5dda5bb7a..d14cb0495 100644 --- a/doc/salome/examples/generate_flat_elements.py +++ b/doc/salome/examples/generate_flat_elements.py @@ -5,7 +5,7 @@ import salome -salome.salome_init() +salome.salome_init_without_session() import GEOM from salome.geom import geomBuilder geompy = geomBuilder.New() diff --git a/doc/salome/examples/grouping_elements_ex02.py b/doc/salome/examples/grouping_elements_ex02.py index 4e2a4957f..16feda41f 100644 --- a/doc/salome/examples/grouping_elements_ex02.py +++ b/doc/salome/examples/grouping_elements_ex02.py @@ -2,7 +2,7 @@ import salome -salome.salome_init() +salome.salome_init_without_session() import GEOM from salome.geom import geomBuilder geompy = geomBuilder.New() diff --git a/doc/salome/examples/grouping_elements_ex03.py b/doc/salome/examples/grouping_elements_ex03.py index 97e1de945..d6d6e83d9 100644 --- a/doc/salome/examples/grouping_elements_ex03.py +++ b/doc/salome/examples/grouping_elements_ex03.py @@ -2,7 +2,7 @@ import salome -salome.salome_init() +salome.salome_init_without_session() import GEOM from salome.geom import geomBuilder geompy = geomBuilder.New() diff --git a/doc/salome/examples/grouping_elements_ex09.py b/doc/salome/examples/grouping_elements_ex09.py index e066dbd1e..988dad3cf 100644 --- a/doc/salome/examples/grouping_elements_ex09.py +++ b/doc/salome/examples/grouping_elements_ex09.py @@ -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() diff --git a/doc/salome/examples/measurements_ex01.py b/doc/salome/examples/measurements_ex01.py index b94f59cbb..b8ccae02a 100644 --- a/doc/salome/examples/measurements_ex01.py +++ b/doc/salome/examples/measurements_ex01.py @@ -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() diff --git a/doc/salome/examples/measurements_ex02.py b/doc/salome/examples/measurements_ex02.py index a11a47dfb..20c04bcc8 100644 --- a/doc/salome/examples/measurements_ex02.py +++ b/doc/salome/examples/measurements_ex02.py @@ -2,7 +2,7 @@ import salome -salome.salome_init() +salome.salome_init_without_session() import GEOM from salome.geom import geomBuilder geompy = geomBuilder.New() diff --git a/doc/salome/examples/measurements_ex03.py b/doc/salome/examples/measurements_ex03.py index d93687883..217d9cb23 100644 --- a/doc/salome/examples/measurements_ex03.py +++ b/doc/salome/examples/measurements_ex03.py @@ -2,7 +2,7 @@ import salome -salome.salome_init() +salome.salome_init_without_session() import GEOM from salome.geom import geomBuilder geompy = geomBuilder.New() diff --git a/doc/salome/examples/measurements_ex04.py b/doc/salome/examples/measurements_ex04.py index 6524ac97a..b143267ba 100644 --- a/doc/salome/examples/measurements_ex04.py +++ b/doc/salome/examples/measurements_ex04.py @@ -2,7 +2,7 @@ import salome -salome.salome_init() +salome.salome_init_without_session() from salome.smesh import smeshBuilder smesh = smeshBuilder.New() diff --git a/doc/salome/examples/modifying_meshes_ex01.py b/doc/salome/examples/modifying_meshes_ex01.py index 5950a00cf..2214610cb 100644 --- a/doc/salome/examples/modifying_meshes_ex01.py +++ b/doc/salome/examples/modifying_meshes_ex01.py @@ -1,7 +1,7 @@ # Add Node import salome -salome.salome_init() +salome.salome_init_without_session() from salome.smesh import smeshBuilder smesh = smeshBuilder.New() diff --git a/doc/salome/examples/modifying_meshes_ex02.py b/doc/salome/examples/modifying_meshes_ex02.py index 78aff713c..7b0b9f348 100644 --- a/doc/salome/examples/modifying_meshes_ex02.py +++ b/doc/salome/examples/modifying_meshes_ex02.py @@ -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() diff --git a/doc/salome/examples/modifying_meshes_ex03.py b/doc/salome/examples/modifying_meshes_ex03.py index 46df84e8f..59198ccd6 100644 --- a/doc/salome/examples/modifying_meshes_ex03.py +++ b/doc/salome/examples/modifying_meshes_ex03.py @@ -2,7 +2,7 @@ import salome -salome.salome_init() +salome.salome_init_without_session() from salome.geom import geomBuilder geompy = geomBuilder.New() diff --git a/doc/salome/examples/modifying_meshes_ex09.py b/doc/salome/examples/modifying_meshes_ex09.py index 057a5d6a2..914e91b5b 100644 --- a/doc/salome/examples/modifying_meshes_ex09.py +++ b/doc/salome/examples/modifying_meshes_ex09.py @@ -1,7 +1,7 @@ # Add Polygon import salome -salome.salome_init() +salome.salome_init_without_session() import SMESH, SALOMEDS from salome.smesh import smeshBuilder diff --git a/doc/salome/examples/modifying_meshes_ex10.py b/doc/salome/examples/modifying_meshes_ex10.py index fe8ec68c6..ed49c4fa6 100644 --- a/doc/salome/examples/modifying_meshes_ex10.py +++ b/doc/salome/examples/modifying_meshes_ex10.py @@ -2,7 +2,7 @@ import salome -salome.salome_init() +salome.salome_init_without_session() from salome.smesh import smeshBuilder smesh = smeshBuilder.New() diff --git a/doc/salome/examples/modifying_meshes_ex15.py b/doc/salome/examples/modifying_meshes_ex15.py index 2656ea300..7d62245e8 100644 --- a/doc/salome/examples/modifying_meshes_ex15.py +++ b/doc/salome/examples/modifying_meshes_ex15.py @@ -2,7 +2,7 @@ import salome -salome.salome_init() +salome.salome_init_without_session() from salome.geom import geomBuilder geompy = geomBuilder.New() diff --git a/doc/salome/examples/modifying_meshes_ex16.py b/doc/salome/examples/modifying_meshes_ex16.py index 2ecc4ed07..82bd0e0cf 100644 --- a/doc/salome/examples/modifying_meshes_ex16.py +++ b/doc/salome/examples/modifying_meshes_ex16.py @@ -2,7 +2,7 @@ import salome -salome.salome_init() +salome.salome_init_without_session() import GEOM from salome.geom import geomBuilder geompy = geomBuilder.New() diff --git a/doc/salome/examples/modifying_meshes_ex17.py b/doc/salome/examples/modifying_meshes_ex17.py index 1fe0c466b..833c5027f 100644 --- a/doc/salome/examples/modifying_meshes_ex17.py +++ b/doc/salome/examples/modifying_meshes_ex17.py @@ -2,7 +2,7 @@ import salome -salome.salome_init() +salome.salome_init_without_session() import GEOM from salome.geom import geomBuilder geompy = geomBuilder.New() diff --git a/doc/salome/examples/modifying_meshes_ex18.py b/doc/salome/examples/modifying_meshes_ex18.py index fd21b376e..738e8d213 100644 --- a/doc/salome/examples/modifying_meshes_ex18.py +++ b/doc/salome/examples/modifying_meshes_ex18.py @@ -2,7 +2,7 @@ import salome -salome.salome_init() +salome.salome_init_without_session() import GEOM from salome.geom import geomBuilder geompy = geomBuilder.New() diff --git a/doc/salome/examples/modifying_meshes_ex19.py b/doc/salome/examples/modifying_meshes_ex19.py index 7e3c723c5..386a3cb56 100644 --- a/doc/salome/examples/modifying_meshes_ex19.py +++ b/doc/salome/examples/modifying_meshes_ex19.py @@ -2,7 +2,7 @@ import salome -salome.salome_init() +salome.salome_init_without_session() import GEOM from salome.geom import geomBuilder geompy = geomBuilder.New() diff --git a/doc/salome/examples/modifying_meshes_ex21.py b/doc/salome/examples/modifying_meshes_ex21.py index a2b92a9f9..6aa3f230d 100644 --- a/doc/salome/examples/modifying_meshes_ex21.py +++ b/doc/salome/examples/modifying_meshes_ex21.py @@ -2,7 +2,7 @@ import salome -salome.salome_init() +salome.salome_init_without_session() import GEOM from salome.geom import geomBuilder geompy = geomBuilder.New() diff --git a/doc/salome/examples/modifying_meshes_ex22.py b/doc/salome/examples/modifying_meshes_ex22.py index fe99d13e3..94ce7561d 100644 --- a/doc/salome/examples/modifying_meshes_ex22.py +++ b/doc/salome/examples/modifying_meshes_ex22.py @@ -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() diff --git a/doc/salome/examples/modifying_meshes_ex23.py b/doc/salome/examples/modifying_meshes_ex23.py index d7f413440..d2f52b229 100644 --- a/doc/salome/examples/modifying_meshes_ex23.py +++ b/doc/salome/examples/modifying_meshes_ex23.py @@ -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() diff --git a/doc/salome/examples/modifying_meshes_ex25.py b/doc/salome/examples/modifying_meshes_ex25.py index 82af9b187..7a6804b06 100644 --- a/doc/salome/examples/modifying_meshes_ex25.py +++ b/doc/salome/examples/modifying_meshes_ex25.py @@ -2,7 +2,7 @@ import salome -salome.salome_init() +salome.salome_init_without_session() import GEOM from salome.geom import geomBuilder geompy = geomBuilder.New() diff --git a/doc/salome/examples/modifying_meshes_ex26.py b/doc/salome/examples/modifying_meshes_ex26.py index 53059ff96..defd6ba1d 100644 --- a/doc/salome/examples/modifying_meshes_ex26.py +++ b/doc/salome/examples/modifying_meshes_ex26.py @@ -2,7 +2,7 @@ import salome -salome.salome_init() +salome.salome_init_without_session() import GEOM from salome.geom import geomBuilder geompy = geomBuilder.New() diff --git a/doc/salome/examples/modifying_meshes_split_vol.py b/doc/salome/examples/modifying_meshes_split_vol.py index 38e8601b3..35eea6aab 100644 --- a/doc/salome/examples/modifying_meshes_split_vol.py +++ b/doc/salome/examples/modifying_meshes_split_vol.py @@ -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() diff --git a/doc/salome/examples/notebook_smesh.py b/doc/salome/examples/notebook_smesh.py index 376e51163..959cc20bd 100644 --- a/doc/salome/examples/notebook_smesh.py +++ b/doc/salome/examples/notebook_smesh.py @@ -2,7 +2,7 @@ import salome -salome.salome_init() +salome.salome_init_without_session() import GEOM from salome.geom import geomBuilder geompy = geomBuilder.New() diff --git a/doc/salome/examples/prism_3d_algo.py b/doc/salome/examples/prism_3d_algo.py index 6c2a9d6d4..06a2c5cc2 100644 --- a/doc/salome/examples/prism_3d_algo.py +++ b/doc/salome/examples/prism_3d_algo.py @@ -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() diff --git a/doc/salome/examples/quad_medial_axis_algo.py b/doc/salome/examples/quad_medial_axis_algo.py index 42aea882e..5937d03ac 100644 --- a/doc/salome/examples/quad_medial_axis_algo.py +++ b/doc/salome/examples/quad_medial_axis_algo.py @@ -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 diff --git a/doc/salome/examples/quality_controls_defl.py b/doc/salome/examples/quality_controls_defl.py index 9c018e8de..97553e02f 100644 --- a/doc/salome/examples/quality_controls_defl.py +++ b/doc/salome/examples/quality_controls_defl.py @@ -2,7 +2,7 @@ import salome -salome.salome_init() +salome.salome_init_without_session() from salome.geom import geomBuilder geompy = geomBuilder.New() diff --git a/doc/salome/examples/quality_controls_ex01.py b/doc/salome/examples/quality_controls_ex01.py index 30648a3ce..2cb3c97fc 100644 --- a/doc/salome/examples/quality_controls_ex01.py +++ b/doc/salome/examples/quality_controls_ex01.py @@ -2,7 +2,7 @@ import salome -salome.salome_init() +salome.salome_init_without_session() import GEOM from salome.geom import geomBuilder geompy = geomBuilder.New() diff --git a/doc/salome/examples/quality_controls_ex02.py b/doc/salome/examples/quality_controls_ex02.py index 62a312ca7..c03942010 100644 --- a/doc/salome/examples/quality_controls_ex02.py +++ b/doc/salome/examples/quality_controls_ex02.py @@ -2,7 +2,7 @@ import salome -salome.salome_init() +salome.salome_init_without_session() import GEOM from salome.geom import geomBuilder geompy = geomBuilder.New() diff --git a/doc/salome/examples/quality_controls_ex03.py b/doc/salome/examples/quality_controls_ex03.py index fca52fddf..65db46bbf 100644 --- a/doc/salome/examples/quality_controls_ex03.py +++ b/doc/salome/examples/quality_controls_ex03.py @@ -2,7 +2,7 @@ import salome -salome.salome_init() +salome.salome_init_without_session() import GEOM from salome.geom import geomBuilder geompy = geomBuilder.New() diff --git a/doc/salome/examples/quality_controls_ex05.py b/doc/salome/examples/quality_controls_ex05.py index 1ec552f75..b01e35cae 100644 --- a/doc/salome/examples/quality_controls_ex05.py +++ b/doc/salome/examples/quality_controls_ex05.py @@ -2,7 +2,7 @@ import salome -salome.salome_init() +salome.salome_init_without_session() import GEOM from salome.geom import geomBuilder geompy = geomBuilder.New() diff --git a/doc/salome/examples/quality_controls_ex06.py b/doc/salome/examples/quality_controls_ex06.py index 8dd8e9cf6..c0cecd4b0 100644 --- a/doc/salome/examples/quality_controls_ex06.py +++ b/doc/salome/examples/quality_controls_ex06.py @@ -2,7 +2,7 @@ import salome -salome.salome_init() +salome.salome_init_without_session() import GEOM from salome.geom import geomBuilder geompy = geomBuilder.New() diff --git a/doc/salome/examples/quality_controls_ex07.py b/doc/salome/examples/quality_controls_ex07.py index e85b27d73..d7f296546 100644 --- a/doc/salome/examples/quality_controls_ex07.py +++ b/doc/salome/examples/quality_controls_ex07.py @@ -2,7 +2,7 @@ import salome -salome.salome_init() +salome.salome_init_without_session() import GEOM from salome.geom import geomBuilder geompy = geomBuilder.New() diff --git a/doc/salome/examples/quality_controls_ex08.py b/doc/salome/examples/quality_controls_ex08.py index 157bf5f8c..8fc367ea0 100644 --- a/doc/salome/examples/quality_controls_ex08.py +++ b/doc/salome/examples/quality_controls_ex08.py @@ -2,7 +2,7 @@ import salome -salome.salome_init() +salome.salome_init_without_session() import GEOM from salome.geom import geomBuilder geompy = geomBuilder.New() diff --git a/doc/salome/examples/quality_controls_ex09.py b/doc/salome/examples/quality_controls_ex09.py index 82050cbc0..9f4f7dbad 100644 --- a/doc/salome/examples/quality_controls_ex09.py +++ b/doc/salome/examples/quality_controls_ex09.py @@ -2,7 +2,7 @@ import salome -salome.salome_init() +salome.salome_init_without_session() import GEOM from salome.geom import geomBuilder geompy = geomBuilder.New() diff --git a/doc/salome/examples/quality_controls_ex10.py b/doc/salome/examples/quality_controls_ex10.py index 1a4287fc7..22e93c9b5 100644 --- a/doc/salome/examples/quality_controls_ex10.py +++ b/doc/salome/examples/quality_controls_ex10.py @@ -2,7 +2,7 @@ import salome -salome.salome_init() +salome.salome_init_without_session() import GEOM from salome.geom import geomBuilder geompy = geomBuilder.New() diff --git a/doc/salome/examples/quality_controls_ex11.py b/doc/salome/examples/quality_controls_ex11.py index 7c00278dc..fbc2b7c5f 100644 --- a/doc/salome/examples/quality_controls_ex11.py +++ b/doc/salome/examples/quality_controls_ex11.py @@ -2,7 +2,7 @@ import salome -salome.salome_init() +salome.salome_init_without_session() import GEOM from salome.geom import geomBuilder geompy = geomBuilder.New() diff --git a/doc/salome/examples/quality_controls_ex12.py b/doc/salome/examples/quality_controls_ex12.py index adedda57d..f6227793c 100644 --- a/doc/salome/examples/quality_controls_ex12.py +++ b/doc/salome/examples/quality_controls_ex12.py @@ -2,7 +2,7 @@ import salome -salome.salome_init() +salome.salome_init_without_session() import GEOM from salome.geom import geomBuilder geompy = geomBuilder.New() diff --git a/doc/salome/examples/radial_prism_3d_algo.py b/doc/salome/examples/radial_prism_3d_algo.py index 6e8c7adba..fe29e52dc 100644 --- a/doc/salome/examples/radial_prism_3d_algo.py +++ b/doc/salome/examples/radial_prism_3d_algo.py @@ -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 diff --git a/doc/salome/examples/split_biquad.py b/doc/salome/examples/split_biquad.py index 235d49157..f9d97b31a 100644 --- a/doc/salome/examples/split_biquad.py +++ b/doc/salome/examples/split_biquad.py @@ -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/test_polyhedron_per_solid.py b/doc/salome/examples/test_polyhedron_per_solid.py index 52fb17c7b..f26bfd718 100644 --- a/doc/salome/examples/test_polyhedron_per_solid.py +++ b/doc/salome/examples/test_polyhedron_per_solid.py @@ -3,7 +3,7 @@ import sys import salome -salome.salome_init() +salome.salome_init_without_session() ### ### GEOM component diff --git a/doc/salome/examples/test_smeshplugin_mg_tetra_parallele.py b/doc/salome/examples/test_smeshplugin_mg_tetra_parallele.py old mode 100755 new mode 100644 index a918da29b..37f5dec38 --- a/doc/salome/examples/test_smeshplugin_mg_tetra_parallele.py +++ b/doc/salome/examples/test_smeshplugin_mg_tetra_parallele.py @@ -13,7 +13,7 @@ ComputeMeshes = True import salome -salome.salome_init() +salome.salome_init_without_session() theStudy = salome.myStudy # import iparameters diff --git a/doc/salome/examples/test_smeshplugins.py b/doc/salome/examples/test_smeshplugins.py old mode 100755 new mode 100644 index 0484092e2..48f12085c --- a/doc/salome/examples/test_smeshplugins.py +++ b/doc/salome/examples/test_smeshplugins.py @@ -18,7 +18,7 @@ ComputeMeshes = True import salome -salome.salome_init() +salome.salome_init_without_session() theStudy = salome.myStudy # import iparameters diff --git a/doc/salome/examples/tests.set b/doc/salome/examples/tests.set index e0293d388..ec4a639a1 100644 --- a/doc/salome/examples/tests.set +++ b/doc/salome/examples/tests.set @@ -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 @@ -197,6 +198,7 @@ set(SESSION_FREE_TESTS basic_geom_smesh_without_session.py basic_shaper_smesh_without_session.py shaper_smesh_groups_without_session.py + basic_smesh_output_with_mc_field.py ) SET(EXAMPLES_TESTS ${BAD_TESTS} ${GOOD_TESTS} ${SESSION_FREE_TESTS} testme.py) diff --git a/doc/salome/examples/transforming_meshes_ex03.py b/doc/salome/examples/transforming_meshes_ex03.py index cf0999c5b..edd4cb438 100644 --- a/doc/salome/examples/transforming_meshes_ex03.py +++ b/doc/salome/examples/transforming_meshes_ex03.py @@ -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() diff --git a/doc/salome/examples/transforming_meshes_ex06.py b/doc/salome/examples/transforming_meshes_ex06.py index 433ae1928..964449fe3 100644 --- a/doc/salome/examples/transforming_meshes_ex06.py +++ b/doc/salome/examples/transforming_meshes_ex06.py @@ -2,7 +2,7 @@ import salome -salome.salome_init() +salome.salome_init_without_session() from salome.geom import geomBuilder geompy = geomBuilder.New() diff --git a/doc/salome/examples/transforming_meshes_ex07.py b/doc/salome/examples/transforming_meshes_ex07.py index f14c2ca62..65865aca5 100644 --- a/doc/salome/examples/transforming_meshes_ex07.py +++ b/doc/salome/examples/transforming_meshes_ex07.py @@ -2,7 +2,7 @@ import salome -salome.salome_init() +salome.salome_init_without_session() import GEOM from salome.geom import geomBuilder geompy = geomBuilder.New() diff --git a/doc/salome/examples/transforming_meshes_ex08.py b/doc/salome/examples/transforming_meshes_ex08.py index b593e0ef1..542bb5f54 100644 --- a/doc/salome/examples/transforming_meshes_ex08.py +++ b/doc/salome/examples/transforming_meshes_ex08.py @@ -2,7 +2,7 @@ import salome -salome.salome_init() +salome.salome_init_without_session() import GEOM from salome.geom import geomBuilder geompy = geomBuilder.New() diff --git a/doc/salome/examples/transforming_meshes_ex09.py b/doc/salome/examples/transforming_meshes_ex09.py index 59403f7db..bbc76691c 100644 --- a/doc/salome/examples/transforming_meshes_ex09.py +++ b/doc/salome/examples/transforming_meshes_ex09.py @@ -2,7 +2,7 @@ import salome -salome.salome_init() +salome.salome_init_without_session() import GEOM from salome.geom import geomBuilder geompy = geomBuilder.New() diff --git a/doc/salome/examples/transforming_meshes_ex10.py b/doc/salome/examples/transforming_meshes_ex10.py index af3d9ff8e..f3de43d21 100644 --- a/doc/salome/examples/transforming_meshes_ex10.py +++ b/doc/salome/examples/transforming_meshes_ex10.py @@ -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() diff --git a/doc/salome/examples/transforming_meshes_ex11.py b/doc/salome/examples/transforming_meshes_ex11.py index 2e6a8c6d5..d4137e41d 100644 --- a/doc/salome/examples/transforming_meshes_ex11.py +++ b/doc/salome/examples/transforming_meshes_ex11.py @@ -2,7 +2,7 @@ import salome -salome.salome_init() +salome.salome_init_without_session() import GEOM from salome.geom import geomBuilder diff --git a/doc/salome/examples/transforming_meshes_ex12.py b/doc/salome/examples/transforming_meshes_ex12.py index 072fc3ca1..65b05d7d5 100644 --- a/doc/salome/examples/transforming_meshes_ex12.py +++ b/doc/salome/examples/transforming_meshes_ex12.py @@ -2,7 +2,7 @@ import salome -salome.salome_init() +salome.salome_init_without_session() import GEOM from salome.geom import geomBuilder geompy = geomBuilder.New() diff --git a/doc/salome/examples/transforming_meshes_ex13.py b/doc/salome/examples/transforming_meshes_ex13.py index 12d03892f..94b6f7f22 100644 --- a/doc/salome/examples/transforming_meshes_ex13.py +++ b/doc/salome/examples/transforming_meshes_ex13.py @@ -2,7 +2,7 @@ import salome -salome.salome_init() +salome.salome_init_without_session() import GEOM from salome.geom import geomBuilder geompy = geomBuilder.New() diff --git a/doc/salome/examples/use_existing_faces.py b/doc/salome/examples/use_existing_faces.py index 0ef132b66..0d4139255 100644 --- a/doc/salome/examples/use_existing_faces.py +++ b/doc/salome/examples/use_existing_faces.py @@ -2,7 +2,7 @@ import salome -salome.salome_init() +salome.salome_init_without_session() import GEOM from salome.geom import geomBuilder geompy = geomBuilder.New() diff --git a/doc/salome/examples/viewing_meshes_ex01.py b/doc/salome/examples/viewing_meshes_ex01.py index d90d24a3a..0e8899eeb 100644 --- a/doc/salome/examples/viewing_meshes_ex01.py +++ b/doc/salome/examples/viewing_meshes_ex01.py @@ -2,7 +2,7 @@ import salome -salome.salome_init() +salome.salome_init_without_session() import GEOM from salome.geom import geomBuilder geompy = geomBuilder.New() diff --git a/doc/salome/examples/viewing_meshes_ex02.py b/doc/salome/examples/viewing_meshes_ex02.py index 0dfa09a85..402e89b97 100644 --- a/doc/salome/examples/viewing_meshes_ex02.py +++ b/doc/salome/examples/viewing_meshes_ex02.py @@ -2,7 +2,7 @@ import salome -salome.salome_init() +salome.salome_init_without_session() import GEOM from salome.geom import geomBuilder geompy = geomBuilder.New() diff --git a/doc/salome/gui/SMESH/input/importing_exporting_meshes.rst b/doc/salome/gui/SMESH/input/importing_exporting_meshes.rst index a11e36dbb..b4ab4d4bd 100644 --- a/doc/salome/gui/SMESH/input/importing_exporting_meshes.rst +++ b/doc/salome/gui/SMESH/input/importing_exporting_meshes.rst @@ -56,6 +56,8 @@ There are additional parameters available at export to MED and SAUV format files * **1D**: if all mesh nodes lie on OX coordinate axis. * **2D**: if all mesh nodes lie in XOY coordinate plane. +* :ref:`Save cell/node numbers to MED file ` preference controls whether node and cell numbers are saved. + **See Also** a sample TUI Script of an :ref:`Export Mesh ` operation. diff --git a/doc/salome/gui/SMESH/input/mesh_preferences.rst b/doc/salome/gui/SMESH/input/mesh_preferences.rst index 027518e91..c7a516734 100644 --- a/doc/salome/gui/SMESH/input/mesh_preferences.rst +++ b/doc/salome/gui/SMESH/input/mesh_preferences.rst @@ -54,6 +54,10 @@ General Preferences * **Show warning when exporting group** - if activated, a warning is displayed when exporting a group. +.. _med_export_numbers_pref: + + * **Save cell/node numbers to MED file** - if activated, optional node and cell numbers are saved to MED file. + .. _medexport_z_tolerance_pref: * **Z tolerance for MED export** - defines Z tolerance in :ref:`MED Export ` dialog. diff --git a/idl/SMESH_Gen.idl b/idl/SMESH_Gen.idl index eeb8f0c71..d5772802b 100644 --- a/idl/SMESH_Gen.idl +++ b/idl/SMESH_Gen.idl @@ -114,7 +114,7 @@ module SMESH short code; // ComputeErrorName or, if negative, algo specific code string comment; // textual problem description string algoName; - short subShapeID; // id of sub-shape of a shape to mesh + long subShapeID; // id of sub-shape of a shape to mesh boolean hasBadMesh; // there are elements preventing computation available for visualization }; typedef sequence compute_error_array; diff --git a/idl/SMESH_Mesh.idl b/idl/SMESH_Mesh.idl index 2ff478b0a..7ee04ecee 100644 --- a/idl/SMESH_Mesh.idl +++ b/idl/SMESH_Mesh.idl @@ -657,11 +657,14 @@ module SMESH * - 3D in the rest cases. * If @a autoDimension is @c false, the space dimension is always 3. */ - void ExportMED( in string fileName, - in boolean auto_groups, - in long version, - in boolean overwrite, - in boolean autoDimension) raises (SALOME::SALOME_Exception); + void ExportMED( in string fileName, + in boolean auto_groups, + in long version, + in boolean overwrite, + in boolean autoDimension) raises (SALOME::SALOME_Exception); + + long long ExportMEDCoupling(in boolean auto_groups, + in boolean autoDimension) raises (SALOME::SALOME_Exception); /*! * Export a [part of] Mesh into a MED file @@ -690,6 +693,7 @@ module SMESH * - ZTolerance : tolerance in Z direction. If Z coordinate of a node is close to zero * within a given tolerance, the coordinate is set to zero. * If @a ZTolerance is negative, the node coordinates are kept as is. + * - saveNumbers : enable saving numbers of nodes and cells. */ void ExportPartToMED( in SMESH_IDSource meshPart, in string fileName, @@ -699,7 +703,16 @@ module SMESH in boolean autoDimension, in GEOM::ListOfFields fields, in string geomAssocFields, - in double ZTolerance) raises (SALOME::SALOME_Exception); + in double ZTolerance, + in boolean saveNumbers) raises (SALOME::SALOME_Exception); + + long long ExportPartToMEDCoupling( in SMESH_IDSource meshPart, + in boolean auto_groups, + in boolean autoDimension, + in GEOM::ListOfFields fields, + in string geomAssocFields, + in double ZTolerance, + in boolean saveNumbers) raises (SALOME::SALOME_Exception); /*! * Export Mesh to SAUV formatted file @@ -723,8 +736,10 @@ module SMESH * Export Mesh to different Formats * (UNV supported version is I-DEAS 10) */ - void ExportDAT( in string file ) raises (SALOME::SALOME_Exception); - void ExportUNV( in string file ) raises (SALOME::SALOME_Exception); + void ExportDAT( in string file, + in boolean renumer) raises (SALOME::SALOME_Exception); + void ExportUNV( in string file, + in boolean renumer ) raises (SALOME::SALOME_Exception); void ExportSTL( in string file, in boolean isascii ) raises (SALOME::SALOME_Exception); void ExportCGNS( in SMESH_IDSource meshPart, @@ -735,9 +750,11 @@ module SMESH in string file, in boolean withRequiredGroups) raises (SALOME::SALOME_Exception); void ExportPartToDAT( in SMESH_IDSource meshPart, - in string file ) raises (SALOME::SALOME_Exception); + in string file, + in boolean renumer ) raises (SALOME::SALOME_Exception); void ExportPartToUNV( in SMESH_IDSource meshPart, - in string file ) raises (SALOME::SALOME_Exception); + in string file, + in boolean renumer ) raises (SALOME::SALOME_Exception); void ExportPartToSTL( in SMESH_IDSource meshPart, in string file, in boolean isascii ) raises (SALOME::SALOME_Exception); @@ -1088,7 +1105,7 @@ module SMESH raises (SALOME::SALOME_Exception); /*! - * Get the internal Id + * Get the internal persisten Id */ long GetId(); }; diff --git a/resources/SalomeApp.xml.in b/resources/SalomeApp.xml.in index c11851f4f..a6190a675 100644 --- a/resources/SalomeApp.xml.in +++ b/resources/SalomeApp.xml.in @@ -66,6 +66,7 @@ + diff --git a/src/Controls/SMESH_ControlsDef.hxx b/src/Controls/SMESH_ControlsDef.hxx index 1ce5f4da5..c1fe797bc 100644 --- a/src/Controls/SMESH_ControlsDef.hxx +++ b/src/Controls/SMESH_ControlsDef.hxx @@ -133,12 +133,12 @@ namespace SMESH{ virtual void SetMesh( const SMDS_Mesh* theMesh ); virtual double GetValue( long theElementId ); virtual double GetValue(const TSequenceOfXYZ& /*thePoints*/) { return -1.0;}; - void GetHistogram(int nbIntervals, - std::vector& nbEvents, - std::vector& funValues, - const std::vector& elements, - const double* minmax=0, - const bool isLogarithmic = false); + void GetHistogram(int nbIntervals, + std::vector& nbEvents, + std::vector& funValues, + const std::vector<::smIdType>& elements, + const double* minmax=0, + const bool isLogarithmic = false); bool IsApplicable( long theElementId ) const; virtual bool IsApplicable( const SMDS_MeshElement* element ) const; virtual SMDSAbs_ElementType GetType() const = 0; @@ -147,7 +147,7 @@ namespace SMESH{ void SetPrecision( const long thePrecision ); double Round( const double & value ); - bool GetPoints(const smIdType theId, TSequenceOfXYZ& theRes) const; + bool GetPoints(const ::smIdType theId, TSequenceOfXYZ& theRes) const; static bool GetPoints(const SMDS_MeshElement* theElem, TSequenceOfXYZ& theRes); protected: const SMDS_Mesh* myMesh; @@ -594,7 +594,7 @@ namespace SMESH{ virtual void SetMesh( const SMDS_Mesh* theMesh ); virtual bool IsSatisfy( long theElementId ); virtual SMDSAbs_ElementType GetType() const; - static bool IsFreeEdge( const SMDS_MeshNode** theNodes, const smIdType theFaceId ); + static bool IsFreeEdge( const SMDS_MeshNode** theNodes, const ::smIdType theFaceId ); typedef long TElemId; struct Border{ TElemId myElemId; @@ -653,8 +653,8 @@ namespace SMESH{ protected: const SMDS_Mesh* myMesh; - std::vector< smIdType > myMin; - std::vector< smIdType > myMax; + std::vector< ::smIdType > myMin; + std::vector< ::smIdType > myMax; TIDsMap myIds; SMDSAbs_ElementType myType; @@ -1165,9 +1165,9 @@ namespace SMESH{ public: ConnectedElements(); //virtual Predicate* clone() const { return new ConnectedElements( *this ); } - void SetNode( smIdType nodeID ); + void SetNode( ::smIdType nodeID ); void SetPoint( double x, double y, double z ); - smIdType GetNode() const; + ::smIdType GetNode() const; std::vector GetPoint() const; void SetType( SMDSAbs_ElementType theType ); @@ -1179,14 +1179,14 @@ namespace SMESH{ //const std::set& GetDomainIDs() const { return myOkIDs; } private: - smIdType myNodeID; - std::vector myXYZ; - SMDSAbs_ElementType myType; - TMeshModifTracer myMeshModifTracer; + ::smIdType myNodeID; + std::vector myXYZ; + SMDSAbs_ElementType myType; + TMeshModifTracer myMeshModifTracer; - void clearOkIDs(); - bool myOkIDsReady; - std::set myOkIDs; // empty means that there is one domain + void clearOkIDs(); + bool myOkIDsReady; + std::set<::smIdType> myOkIDs; // empty means that there is one domain }; typedef boost::shared_ptr ConnectedElementsPtr; diff --git a/src/Driver/Driver_Mesh.h b/src/Driver/Driver_Mesh.h index 9eac8fc88..8ec3bac1f 100644 --- a/src/Driver/Driver_Mesh.h +++ b/src/Driver/Driver_Mesh.h @@ -32,6 +32,7 @@ #include #include +#include #ifdef WIN32 #if defined MESHDRIVER_EXPORTS || defined MeshDriver_EXPORTS @@ -79,7 +80,7 @@ class MESHDRIVER_EXPORT Driver_Mesh { if ( sizeof( IDTYPE ) < sizeof( smIdType )) { - const smIdType maxNB = std::numeric_limits< IDTYPE >::max(); + const smIdType maxNB = ToSmIdType( std::numeric_limits< IDTYPE >::max() ); return (( checkIDs ? mesh->MaxNodeID() : mesh->NbNodes() ) > maxNB || ( checkIDs ? mesh->MaxElementID() : mesh->NbElements() > maxNB )); } diff --git a/src/DriverDAT/DriverDAT_R_SMDS_Mesh.cxx b/src/DriverDAT/DriverDAT_R_SMDS_Mesh.cxx index 27fa48bbb..d0f233ecc 100644 --- a/src/DriverDAT/DriverDAT_R_SMDS_Mesh.cxx +++ b/src/DriverDAT/DriverDAT_R_SMDS_Mesh.cxx @@ -76,7 +76,7 @@ Driver_Mesh::Status DriverDAT_R_SMDS_Mesh::Perform() myMesh->AddNodeWithID(coordX, coordY, coordZ, intNumPoint); } - fprintf(stdout, "%ld noeuds\n", myMesh->NbNodes()); + fprintf(stdout, "%ld noeuds\n", static_cast< long >( myMesh->NbNodes() )); /**************************************************************************** * LECTURE DES ELEMENTS * ****************************************************************************/ diff --git a/src/DriverDAT/DriverDAT_W_SMDS_Mesh.cxx b/src/DriverDAT/DriverDAT_W_SMDS_Mesh.cxx index 2eb69bd07..70b2d073a 100644 --- a/src/DriverDAT/DriverDAT_W_SMDS_Mesh.cxx +++ b/src/DriverDAT/DriverDAT_W_SMDS_Mesh.cxx @@ -32,6 +32,14 @@ using namespace std; +//================================================================================ +/*! + * \brief Write mesh data to a file + * \param [in] renumber - if true, renumber nodes and cell starting from 1 + * \return Driver_Mesh::Status - Ok or not + */ +//================================================================================ + Driver_Mesh::Status DriverDAT_W_SMDS_Mesh::Perform() { Kernel_Utils::Localizer loc; @@ -70,21 +78,24 @@ Driver_Mesh::Status DriverDAT_W_SMDS_Mesh::Perform() SCRUTE(nb_of_volumes); //fprintf(stdout, "%d %d\n", nbNodes, nbCells); - fprintf(aFileId, "%ld %ld\n", nbNodes, nbCells); + fprintf(aFileId, "%ld %ld\n", static_cast< long >( nbNodes ), static_cast< long >( nbCells )); /**************************************************************************** * ECRITURE DES NOEUDS * ****************************************************************************/ std::vector< size_t > nodeNumByID; - if ( myMesh->HasNumerationHoles() ) + if ( myRenumber && myMesh->HasNumerationHoles() ) nodeNumByID.resize( myMesh->MaxNodeID() + 1 ); - int num; + smIdType num; SMDS_NodeIteratorPtr itNodes=myMesh->nodesIterator(); for ( num = 1; itNodes->more(); ++num ) { const SMDS_MeshNode * node = itNodes->next(); + if ( !myRenumber ) + num = node->GetID(); + fprintf(aFileId, "%d %.14e %.14e %.14e\n", num, node->X(), node->Y(), node->Z()); if ( !nodeNumByID.empty() ) @@ -100,6 +111,9 @@ Driver_Mesh::Status DriverDAT_W_SMDS_Mesh::Perform() for ( SMDS_EdgeIteratorPtr itEdges = myMesh->edgesIterator(); itEdges->more(); ++num ) { const SMDS_MeshElement * elem = itEdges->next(); + if ( !myRenumber ) + num = elem->GetID(); + fprintf(aFileId, "%d %d ", num, 100 + elem->NbNodes()); for ( SMDS_ElemIteratorPtr it = elem->nodesIterator(); it->more(); ) @@ -107,7 +121,7 @@ Driver_Mesh::Status DriverDAT_W_SMDS_Mesh::Perform() smIdType nodeID = it->next()->GetID(); if ( !nodeNumByID.empty() ) nodeID = nodeNumByID[ nodeID ]; - fprintf(aFileId, "%ld ", nodeID ); + fprintf(aFileId, "%ld ", static_cast< long >( nodeID )); } fprintf(aFileId, "\n"); } @@ -115,6 +129,8 @@ Driver_Mesh::Status DriverDAT_W_SMDS_Mesh::Perform() for ( SMDS_FaceIteratorPtr itFaces = myMesh->facesIterator(); itFaces->more(); ++num ) { const SMDS_MeshElement * elem = itFaces->next(); + if ( !myRenumber ) + num = elem->GetID(); fprintf(aFileId, "%d %d ", num, (elem->IsPoly() ? 400 : 200 ) + elem->NbNodes() ); @@ -123,7 +139,7 @@ Driver_Mesh::Status DriverDAT_W_SMDS_Mesh::Perform() smIdType nodeID = it->next()->GetID(); if ( !nodeNumByID.empty() ) nodeID = nodeNumByID[ nodeID ]; - fprintf(aFileId, "%ld ", nodeID ); + fprintf(aFileId, "%ld ", static_cast< long >( nodeID )); } fprintf(aFileId, "\n"); } @@ -133,6 +149,9 @@ Driver_Mesh::Status DriverDAT_W_SMDS_Mesh::Perform() for ( SMDS_VolumeIteratorPtr itVolumes=myMesh->volumesIterator(); itVolumes->more(); ++num ) { const SMDS_MeshElement * elem = itVolumes->next(); + if ( !myRenumber ) + num = elem->GetID(); + if ( elem->IsPoly() ) { fprintf(aFileId, "%d %d ", num, 500 + elem->NbNodes()); @@ -158,7 +177,7 @@ Driver_Mesh::Status DriverDAT_W_SMDS_Mesh::Perform() smIdType nodeID = it->next()->GetID(); if ( !nodeNumByID.empty() ) nodeID = nodeNumByID[ nodeID ]; - fprintf(aFileId, "%ld ", nodeID ); + fprintf(aFileId, "%ld ", static_cast< long >( nodeID )); } fprintf(aFileId, "\n"); diff --git a/src/DriverDAT/DriverDAT_W_SMDS_Mesh.h b/src/DriverDAT/DriverDAT_W_SMDS_Mesh.h index 75c3f37fb..481f5b080 100644 --- a/src/DriverDAT/DriverDAT_W_SMDS_Mesh.h +++ b/src/DriverDAT/DriverDAT_W_SMDS_Mesh.h @@ -34,7 +34,12 @@ class MESHDRIVERDAT_EXPORT DriverDAT_W_SMDS_Mesh: public Driver_SMDS_Mesh { public: - virtual Status Perform(); + virtual Status Perform() override; + void SetRenumber( bool renumber ) { myRenumber = renumber; } + + private: + + bool myRenumber; }; #endif diff --git a/src/DriverMED/CMakeLists.txt b/src/DriverMED/CMakeLists.txt index a1dcd1a49..2186564d4 100644 --- a/src/DriverMED/CMakeLists.txt +++ b/src/DriverMED/CMakeLists.txt @@ -20,6 +20,7 @@ # --- options --- # additional include directories INCLUDE_DIRECTORIES( + ${MEDCOUPLING_INCLUDE_DIRS} ${MEDFILE_INCLUDE_DIRS} ${HDF5_INCLUDE_DIRS} ${KERNEL_INCLUDE_DIRS} diff --git a/src/DriverMED/DriverMED_Family.cxx b/src/DriverMED/DriverMED_Family.cxx index 2acd6a826..f5b00968a 100644 --- a/src/DriverMED/DriverMED_Family.cxx +++ b/src/DriverMED/DriverMED_Family.cxx @@ -26,7 +26,6 @@ // Module : SMESH // #include "DriverMED_Family.h" -#include "MED_Factory.hxx" #include @@ -366,67 +365,6 @@ DriverMED_Family return aFamilies; } -//============================================================================= -/*! - * Create TFamilyInfo for this family - */ -//============================================================================= -MED::PFamilyInfo -DriverMED_Family::GetFamilyInfo(const MED::PWrapper& theWrapper, - const MED::PMeshInfo& theMeshInfo) const -{ - ostringstream aStr; - aStr << "FAM_" << myId; - set::const_iterator aGrIter = myGroupNames.begin(); - for(; aGrIter != myGroupNames.end(); aGrIter++){ - aStr << "_" << *aGrIter; - } - string aValue = aStr.str(); - // PAL19785,0019867 - med forbids whitespace to be the last char in the name - int maxSize = MED::GetNOMLength(); - int lastCharPos = min( maxSize, (int) aValue.size() ) - 1; - while ( isspace( aValue[ lastCharPos ] )) - aValue.resize( lastCharPos-- ); - - MED::PFamilyInfo anInfo; - if(myId == 0 || myGroupAttributVal == 0){ - anInfo = theWrapper->CrFamilyInfo(theMeshInfo, - aValue, - myId, - myGroupNames); - }else{ - MED::TStringVector anAttrDescs (1, ""); // 1 attribute with empty description, - MED::TIntVector anAttrIds (1, myId); // Id=0, - MED::TIntVector anAttrVals (1, myGroupAttributVal); - anInfo = theWrapper->CrFamilyInfo(theMeshInfo, - aValue, - myId, - myGroupNames, - anAttrDescs, - anAttrIds, - anAttrVals); - } - -// cout << endl; -// cout << "Groups: "; -// set::iterator aGrIter = myGroupNames.begin(); -// for (; aGrIter != myGroupNames.end(); aGrIter++) -// { -// cout << " " << *aGrIter; -// } -// cout << endl; -// -// cout << "Elements: "; -// set::iterator anIter = myElements.begin(); -// for (; anIter != myElements.end(); anIter++) -// { -// cout << " " << (*anIter)->GetID(); -// } -// cout << endl; - - return anInfo; -} - //============================================================================= /*! * Initialize the tool by SMESHDS_GroupBase diff --git a/src/DriverMED/DriverMED_Family.h b/src/DriverMED/DriverMED_Family.h index d102b87a9..bdbf84301 100644 --- a/src/DriverMED/DriverMED_Family.h +++ b/src/DriverMED/DriverMED_Family.h @@ -91,9 +91,10 @@ class MESHDRIVERMED_EXPORT DriverMED_Family const bool doAllInGroups); //! Create TFamilyInfo for this family + template MED::PFamilyInfo - GetFamilyInfo (const MED::PWrapper& theWrapper, - const MED::PMeshInfo& theMeshInfo) const; + GetFamilyInfo(const LowLevelWriter& theWrapper, + const MED::PMeshInfo& theMeshInfo) const; //! Returns elements of this family const ElementsSet& GetElements () const; @@ -154,4 +155,70 @@ class MESHDRIVERMED_EXPORT DriverMED_Family ElemTypeSet myTypes; // Issue 0020576 }; +#include "MED_Factory.hxx" + +#include +#include +//============================================================================= +/*! + * Create TFamilyInfo for this family + */ +//============================================================================= +template +MED::PFamilyInfo +DriverMED_Family::GetFamilyInfo(const LowLevelWriter& theWrapper, + const MED::PMeshInfo& theMeshInfo) const +{ + std::ostringstream aStr; + aStr << "FAM_" << myId; + std::set::const_iterator aGrIter = myGroupNames.begin(); + for(; aGrIter != myGroupNames.end(); aGrIter++){ + aStr << "_" << *aGrIter; + } + std::string aValue = aStr.str(); + // PAL19785,0019867 - med forbids whitespace to be the last char in the name + int maxSize = MED::GetNOMLength(); + int lastCharPos = std::min( maxSize, (int) aValue.size() ) - 1; + while ( isspace( aValue[ lastCharPos ] )) + aValue.resize( lastCharPos-- ); + + MED::PFamilyInfo anInfo; + if(myId == 0 || myGroupAttributVal == 0){ + anInfo = theWrapper->CrFamilyInfo(theMeshInfo, + aValue, + myId, + myGroupNames); + }else{ + MED::TStringVector anAttrDescs (1, ""); // 1 attribute with empty description, + MED::TIntVector anAttrIds (1, myId); // Id=0, + MED::TIntVector anAttrVals (1, myGroupAttributVal); + anInfo = theWrapper->CrFamilyInfo(theMeshInfo, + aValue, + myId, + myGroupNames, + anAttrDescs, + anAttrIds, + anAttrVals); + } + +// cout << endl; +// cout << "Groups: "; +// set::iterator aGrIter = myGroupNames.begin(); +// for (; aGrIter != myGroupNames.end(); aGrIter++) +// { +// cout << " " << *aGrIter; +// } +// cout << endl; +// +// cout << "Elements: "; +// set::iterator anIter = myElements.begin(); +// for (; anIter != myElements.end(); anIter++) +// { +// cout << " " << (*anIter)->GetID(); +// } +// cout << endl; + + return anInfo; +} + #endif diff --git a/src/DriverMED/DriverMED_W_Field.cxx b/src/DriverMED/DriverMED_W_Field.cxx index 041d1e8dd..1db5c32a8 100644 --- a/src/DriverMED/DriverMED_W_Field.cxx +++ b/src/DriverMED/DriverMED_W_Field.cxx @@ -29,12 +29,14 @@ #include "DriverMED.hxx" #include "DriverMED_W_SMESHDS_Mesh.h" #include "MED_Factory.hxx" +#include "MED_TFile.hxx" #include "MED_Utilities.hxx" #include "MED_Wrapper.hxx" #include "SMDS_IteratorOnIterators.hxx" #include "SMDS_MeshElement.hxx" #include "SMDS_SetIterator.hxx" #include "SMESHDS_Mesh.hxx" +#include "SMESH_TypeDefs.hxx" //================================================================================ /*! @@ -97,10 +99,10 @@ bool DriverMED_W_Field::Set(SMESHDS_Mesh * mesh, _nbElemsByGeom.resize( 1, std::make_pair( SMDSEntity_Last, 0 )); // count nb of elems of each geometry - for ( int iG = 0; iG < SMDSEntity_Last; ++iG ) + SMDSAbs_EntityType geom = SMDSEntity_0D; + for ( ; geom < SMDSEntity_Last; SMESHUtils::Increment( geom )) { - SMDSAbs_EntityType geom = (SMDSAbs_EntityType) iG; - SMDSAbs_ElementType t = SMDS_MeshCell::ElemType( geom ); + SMDSAbs_ElementType t = SMDS_MeshCell::ElemType( geom ); if ( t != _elemType ) continue; nbElems = mesh->GetMeshInfo().NbElements( geom ); @@ -236,16 +238,8 @@ SMDS_ElemIteratorPtr DriverMED_W_Field::GetOrderedElems() return SMDS_ElemIteratorPtr( new TItIterator( iterVec )); } -//================================================================================ -/*! - * Writes a field to the file - */ -//================================================================================ - -Driver_Mesh::Status DriverMED_W_Field::Perform() +Driver_Mesh::Status DriverMED_W_Field::PerformInternal(MED::PWrapper& medFile) { - if ( myFile.empty() ) - return addMessage("File name not set", /*isFatal=*/true ); // 'fatal' means 'bug' if ( myMeshId < 0 && myMeshName.empty() ) return addMessage("Mesh in file not specified", /*isFatal=*/true ); if ( _nbElemsByGeom.size() < 2 ) @@ -253,11 +247,6 @@ Driver_Mesh::Status DriverMED_W_Field::Perform() if ( !myMesh ) return addMessage("Supporting mesh not set", /*isFatal=*/true ); - int version = -1, major, minor, release; - if ( MED::GetMEDVersion( myFile, major, minor, release )) - version = major * 10 + minor; - - MED::PWrapper medFile = MED::CrWrapperW( myFile, version ); MED::PMeshInfo meshInfo; if ( myMeshId > 0 ) { @@ -361,6 +350,44 @@ Driver_Mesh::Status DriverMED_W_Field::Perform() return DRS_OK; } +/*! + * Writes a field to the file + */ +Driver_Mesh::Status DriverMED_W_Field::Perform() +{ + if ( myFile.empty() ) + return addMessage("File name not set", /*isFatal=*/true ); // 'fatal' means 'bug' + int version = -1, major, minor, release; + if ( MED::GetMEDVersion( myFile, major, minor, release )) + version = major * 10 + minor; + + MED::PWrapper medFile = MED::CrWrapperW( myFile, version ); + return this->PerformInternal(medFile); +} + +/*! + * Writes a field to a chunck of memory + */ +Driver_Mesh::Status DriverMED_W_Field_Mem::Perform() +{ + Driver_Mesh::Status status = Driver_Mesh::DRS_OK; + bool isClosed(false); + void *ptr(_data->getPointer()); + std::size_t sz(_data->getNumberOfTuples()); + _data->accessToMemArray().setSpecificDeallocator(nullptr); + _data->useArray(nullptr,false,MEDCoupling::DeallocType::C_DEALLOC,0,1); + {// let braces to flush (call of MED::PWrapper myMed destructor) + MED::TMemFile *tfileInst = new MED::TMemFile(&ptr,&sz,&isClosed); + MED::PWrapper myMed = MED::CrWrapperW(myFile, -1, tfileInst); + status = this->PerformInternal(myMed); + } + if(!isClosed) + EXCEPTION(std::runtime_error, "TFTMemFile destructor : on destruction file has not been closed properly -> chunk of memory data may be invalid !"); + _data = MEDCoupling::DataArrayByte::New(); + _data->useArray(reinterpret_cast(ptr),true,MEDCoupling::DeallocType::C_DEALLOC,sz,1); + return status; +} + namespace DriverMED // Implementation of functions declared in DriverMED.hxx { //================================================================================ diff --git a/src/DriverMED/DriverMED_W_Field.h b/src/DriverMED/DriverMED_W_Field.h index 03168e7cb..d34382371 100644 --- a/src/DriverMED/DriverMED_W_Field.h +++ b/src/DriverMED/DriverMED_W_Field.h @@ -31,6 +31,7 @@ #include "Driver_SMESHDS_Mesh.h" #include "SMDSAbs_ElementType.hxx" #include "SMDS_ElemIterator.hxx" +#include "MED_Common.hxx" #include #include @@ -64,8 +65,12 @@ class MESHDRIVERMED_EXPORT DriverMED_W_Field: public Driver_SMESHDS_Mesh /* * Add one field to the file */ - virtual Status Perform(); + Status Perform() override; + protected: + + Status PerformInternal(MED::PWrapper& medFile); + private: std::string _fieldName; @@ -80,4 +85,16 @@ class MESHDRIVERMED_EXPORT DriverMED_W_Field: public Driver_SMESHDS_Mesh std::vector< std::pair< SMDSAbs_EntityType, int > > _nbElemsByGeom; }; +#include "MEDCouplingMemArray.hxx" + +class MESHDRIVERMED_EXPORT DriverMED_W_Field_Mem : public DriverMED_W_Field +{ +public: + DriverMED_W_Field_Mem(MEDCoupling::MCAuto data):_data(data) { } + Status Perform() override; + MEDCoupling::MCAuto getData() const { return _data; } +private: + MEDCoupling::MCAuto _data; +}; + #endif diff --git a/src/DriverMED/DriverMED_W_SMESHDS_Mesh.cxx b/src/DriverMED/DriverMED_W_SMESHDS_Mesh.cxx index b0d98d2c3..5076ae51d 100644 --- a/src/DriverMED/DriverMED_W_SMESHDS_Mesh.cxx +++ b/src/DriverMED/DriverMED_W_SMESHDS_Mesh.cxx @@ -35,6 +35,7 @@ #include "SMDS_SetIterator.hxx" #include "SMESHDS_Mesh.hxx" #include "MED_Common.hxx" +#include "MED_TFile.hxx" #include @@ -52,6 +53,12 @@ using namespace std; using namespace MED; +//================================================================================ +/*! + * \brief Constructor + */ +//================================================================================ + DriverMED_W_SMESHDS_Mesh::DriverMED_W_SMESHDS_Mesh(): myAllSubMeshes (false), myDoGroupOfNodes (false), @@ -64,19 +71,31 @@ DriverMED_W_SMESHDS_Mesh::DriverMED_W_SMESHDS_Mesh(): myAddODOnVertices(false), myDoAllInGroups(false), myVersion(-1), - myZTolerance(-1.) + myZTolerance(-1.), + mySaveNumbers(true) {} +//================================================================================ +/*! + * \brief Set a file name and a version + * \param [in] theFileName - output file name + * \param [in] theVersion - desired MED file version == major * 10 + minor + */ +//================================================================================ + void DriverMED_W_SMESHDS_Mesh::SetFile(const std::string& theFileName, int theVersion) { myVersion = theVersion; Driver_SMESHDS_Mesh::SetFile(theFileName); } +//================================================================================ /*! * MED version is either the latest available, or with an inferior minor, * to ensure backward compatibility on writing med files. */ +//================================================================================ + string DriverMED_W_SMESHDS_Mesh::GetVersionString(int theMinor, int theNbDigits) { TInt majeur, mineur, release; @@ -165,6 +184,12 @@ void DriverMED_W_SMESHDS_Mesh::AddAllToGroup() namespace { + //--------------------------------------------- + /*! + * \brief Retrieving node coordinates utilities + */ + //--------------------------------------------- + typedef double (SMDS_MeshNode::* TGetCoord)() const; typedef const char* TName; typedef const char* TUnit; @@ -345,11 +370,50 @@ namespace //================================================================================ /*! - * \brief Write my mesh + * \brief Write my mesh to a file */ //================================================================================ Driver_Mesh::Status DriverMED_W_SMESHDS_Mesh::Perform() +{ + MED::PWrapper myMed = CrWrapperW(myFile, myVersion); + return this->PerformInternal(myMed); +} + +//================================================================================ +/*! + * \brief Write my mesh to a MEDCoupling DS + */ +//================================================================================ + +Driver_Mesh::Status DriverMED_W_SMESHDS_Mesh_Mem::Perform() +{ + void *ptr(nullptr); + std::size_t sz(0); + Driver_Mesh::Status status = Driver_Mesh::DRS_OK; + bool isClosed(false); + {// let braces to flush (call of MED::PWrapper myMed destructor) + TMemFile *tfileInst = new TMemFile(&ptr,&sz,&isClosed);// this new will be destroyed by destructor of myMed + MED::PWrapper myMed = CrWrapperW(myFile, -1, tfileInst); + status = this->PerformInternal(myMed); + } + if(!isClosed) + EXCEPTION(std::runtime_error, "TFTMemFile destructor : on destruction file has not been closed properly -> chunk of memory data may be invalid !"); + _data = MEDCoupling::DataArrayByte::New(); + _data->useArray(reinterpret_cast(ptr),true,MEDCoupling::DeallocType::C_DEALLOC,sz,1); + if(!isClosed) + THROW_SALOME_EXCEPTION("DriverMED_W_SMESHDS_Mesh_Mem::Perform - MED memory file id is supposed to be closed !"); + return status; +} + +//================================================================================ +/*! + * \brief Write my mesh + */ +//================================================================================ + +template +Driver_Mesh::Status DriverMED_W_SMESHDS_Mesh::PerformInternal(LowLevelWriter myMed) { Status aResult = DRS_OK; try { @@ -471,7 +535,6 @@ Driver_Mesh::Status DriverMED_W_SMESHDS_Mesh::Perform() } } - MED::PWrapper myMed = CrWrapperW(myFile, myVersion); PMeshInfo aMeshInfo = myMed->CrMeshInfo(aMeshDimension,aSpaceDimension,aMeshName); //MESSAGE("Add - aMeshName : "<GetName()); myMed->SetMeshInfo(aMeshInfo); @@ -532,7 +595,7 @@ Driver_Mesh::Status DriverMED_W_SMESHDS_Mesh::Perform() list::iterator aFamsIter; for (aFamsIter = aFamilies.begin(); aFamsIter != aFamilies.end(); aFamsIter++) { - PFamilyInfo aFamilyInfo = (*aFamsIter)->GetFamilyInfo(myMed,aMeshInfo); + PFamilyInfo aFamilyInfo = (*aFamsIter)->GetFamilyInfo(myMed,aMeshInfo); myMed->SetFamilyInfo(aFamilyInfo); } @@ -544,7 +607,7 @@ Driver_Mesh::Status DriverMED_W_SMESHDS_Mesh::Perform() #endif const EModeSwitch theMode = eFULL_INTERLACE; const ERepere theSystem = eCART; - const EBooleen theIsElemNum = eVRAI; + const EBooleen theIsElemNum = mySaveNumbers ? eVRAI : eFAUX; const EBooleen theIsElemNames = eFAUX; const EConnectivite theConnMode = eNOD; @@ -973,9 +1036,11 @@ Driver_Mesh::Status DriverMED_W_SMESHDS_Mesh::Perform() theIsElemNames); TInt aNbNodes = MED::GetNbNodes(aElemTypeData->_geomType); + elemIterator = myMesh->elementsIterator( aElemTypeData->_smdsType ); if ( aElemTypeData->_smdsType == SMDSAbs_0DElement && ! nodesOf0D.empty() ) elemIterator = iterVecIter; + while ( elemIterator->more() ) { const SMDS_MeshElement* anElem = elemIterator->next(); @@ -1002,6 +1067,15 @@ Driver_Mesh::Status DriverMED_W_SMESHDS_Mesh::Perform() if ( ++iElem == aCellInfo->GetNbElem() ) break; } + // fix numbers of added SMDSAbs_0DElement + if ( aElemTypeData->_smdsType == SMDSAbs_0DElement && ! nodesOf0D.empty() ) + { + iElem = myMesh->Nb0DElements(); + TInt elem0DNum = FromSmIdType( myMesh->MaxElementID() + 1 ); + for ( size_t i = 0; i < nodesOf0D.size(); ++i ) + aCellInfo->SetElemNum( iElem++, elem0DNum++); + } + // store data in a file myMed->SetCellInfo(aCellInfo); } diff --git a/src/DriverMED/DriverMED_W_SMESHDS_Mesh.h b/src/DriverMED/DriverMED_W_SMESHDS_Mesh.h index 96196aa75..43e5c2745 100644 --- a/src/DriverMED/DriverMED_W_SMESHDS_Mesh.h +++ b/src/DriverMED/DriverMED_W_SMESHDS_Mesh.h @@ -42,6 +42,9 @@ class SMESHDS_GroupBase; class SMESHDS_SubMesh; class SMDS_MeshElement; +/*! + * \brief Write a mesh to a MED file + */ class MESHDRIVERMED_EXPORT DriverMED_W_SMESHDS_Mesh: public Driver_SMESHDS_Mesh { public: @@ -51,6 +54,7 @@ class MESHDRIVERMED_EXPORT DriverMED_W_SMESHDS_Mesh: public Driver_SMESHDS_Mesh void SetFile(const std::string& theFileName, int theVersion=-1); void SetAutoDimension(bool toFindOutDimension) { myAutoDimension = toFindOutDimension; } void SetZTolerance(double tol) { myZTolerance = tol; } + void SetSaveNumbers(bool toSave) { mySaveNumbers = toSave; } static std::string GetVersionString(int theMinor, int theNbDigits=2); @@ -74,24 +78,42 @@ class MESHDRIVERMED_EXPORT DriverMED_W_SMESHDS_Mesh: public Driver_SMESHDS_Mesh /*! add one mesh */ - virtual Status Perform(); + Status Perform() override; + + template + Driver_Mesh::Status PerformInternal(LowLevelWriter myMed); private: std::list myGroups; - bool myAllSubMeshes; + bool myAllSubMeshes; std::vector mySubMeshes; - bool myDoGroupOfNodes; - bool myDoGroupOfEdges; - bool myDoGroupOfFaces; - bool myDoGroupOfVolumes; - bool myDoGroupOf0DElems; - bool myDoGroupOfBalls; - bool myAutoDimension; - bool myAddODOnVertices; - bool myDoAllInGroups; - int myVersion; - double myZTolerance; + bool myDoGroupOfNodes; + bool myDoGroupOfEdges; + bool myDoGroupOfFaces; + bool myDoGroupOfVolumes; + bool myDoGroupOf0DElems; + bool myDoGroupOfBalls; + bool myAutoDimension; + bool myAddODOnVertices; + bool myDoAllInGroups; + int myVersion; + double myZTolerance; + bool mySaveNumbers; +}; + +#include "MEDCouplingMemArray.hxx" + +/*! + * \brief Write a mesh to a MEDCoupling DS + */ +class MESHDRIVERMED_EXPORT DriverMED_W_SMESHDS_Mesh_Mem : public DriverMED_W_SMESHDS_Mesh +{ +public: + Status Perform() override; + MEDCoupling::MCAuto getData() { return _data; } +private: + MEDCoupling::MCAuto _data; }; #endif diff --git a/src/DriverUNV/DriverUNV_W_SMDS_Mesh.cxx b/src/DriverUNV/DriverUNV_W_SMDS_Mesh.cxx index 2263c1530..68c33035c 100644 --- a/src/DriverUNV/DriverUNV_W_SMDS_Mesh.cxx +++ b/src/DriverUNV/DriverUNV_W_SMDS_Mesh.cxx @@ -55,13 +55,13 @@ Driver_Mesh::Status DriverUNV_W_SMDS_Mesh::Perform() #else std::ofstream out_stream(myFile.c_str()); #endif - try{ - + try + { UNV164::Write( out_stream ); // unit system UNV2420::Write( out_stream, myMeshName ); // Coordinate system std::vector< size_t > nodeLabelByID; - if ( myMesh->HasNumerationHoles() ) + if ( myMesh->HasNumerationHoles() && myRenumber ) nodeLabelByID.resize( myMesh->MaxNodeID() + 1 ); { @@ -75,7 +75,8 @@ Driver_Mesh::Status DriverUNV_W_SMDS_Mesh::Perform() for ( aRec.label = 1; aNodesIter->more(); ++aRec.label ) { const SMDS_MeshNode* aNode = aNodesIter->next(); - // aRec.label = aNode->GetID(); -- IPAL54452 + if ( !myRenumber ) + aRec.label = aNode->GetID(); //-- IPAL54452 if ( !nodeLabelByID.empty() ) nodeLabelByID[ aNode->GetID() ] = aRec.label; aRec.coord[0] = aNode->X(); @@ -105,8 +106,10 @@ Driver_Mesh::Status DriverUNV_W_SMDS_Mesh::Perform() while ( anIter->more() ) { const SMDS_MeshEdge* anElem = anIter->next(); - // aRec.label = anElem->GetID(); -- IPAL54452 - ++aRec.label; + if ( myRenumber ) // -- IPAL54452 + ++aRec.label; + else + aRec.label = anElem->GetID(); if ( !elemLabelByID.empty() ) elemLabelByID[ anElem->GetID() ] = aRec.label; @@ -138,7 +141,8 @@ Driver_Mesh::Status DriverUNV_W_SMDS_Mesh::Perform() if ( anElem->IsPoly() ) continue; SMDS_NodeIteratorPtr aNodesIter = anElem->nodesIteratorToUNV(); - for ( aRec.node_labels.clear(); aNodesIter->more(); ) { + for ( aRec.node_labels.clear(); aNodesIter->more(); ) + { const SMDS_MeshNode* aNode = aNodesIter->next(); if ( nodeLabelByID.empty() ) aRec.node_labels.push_back( FromSmIdType(aNode->GetID()) ); @@ -155,8 +159,10 @@ Driver_Mesh::Status DriverUNV_W_SMDS_Mesh::Perform() default: continue; } - // aRec.label = anElem->GetID(); -- IPAL54452 - ++aRec.label; + if ( myRenumber ) + ++aRec.label; + else + aRec.label = anElem->GetID(); // -- IPAL54452 if ( !elemLabelByID.empty() ) elemLabelByID[ anElem->GetID() ] = aRec.label; @@ -188,8 +194,10 @@ Driver_Mesh::Status DriverUNV_W_SMDS_Mesh::Perform() default: continue; } - // aRec.label = anElem->GetID(); -- IPAL54452 - ++aRec.label; + if ( myRenumber ) + ++aRec.label; // -- IPAL54452 + else + aRec.label = anElem->GetID(); if ( !elemLabelByID.empty() ) elemLabelByID[ anElem->GetID() ] = aRec.label; @@ -214,7 +222,8 @@ Driver_Mesh::Status DriverUNV_W_SMDS_Mesh::Perform() // -------------------- { using namespace UNV2417; - if ( myGroups.size() > 0 ) { + if ( myGroups.size() > 0 ) + { TRecord aRec; TDataSet aDataSet2417; TGroupList::const_iterator aIter = myGroups.begin(); @@ -230,7 +239,7 @@ Driver_Mesh::Status DriverUNV_W_SMDS_Mesh::Perform() while ( aIter->more() ) { const SMDS_MeshElement* aNode = aIter->next(); if ( nodeLabelByID.empty() ) - aRec.NodeList.push_back( FromSmIdType(aNode->GetID()) ); + aRec.NodeList.push_back( FromSmIdType( aNode->GetID()) ); else aRec.NodeList.push_back( nodeLabelByID[ aNode->GetID() ]); } diff --git a/src/DriverUNV/DriverUNV_W_SMDS_Mesh.h b/src/DriverUNV/DriverUNV_W_SMDS_Mesh.h index 00ecb02c5..008123eb5 100644 --- a/src/DriverUNV/DriverUNV_W_SMDS_Mesh.h +++ b/src/DriverUNV/DriverUNV_W_SMDS_Mesh.h @@ -39,9 +39,11 @@ class MESHDRIVERUNV_EXPORT DriverUNV_W_SMDS_Mesh: public Driver_SMDS_Mesh virtual Status Perform() override; void AddGroup(SMESHDS_GroupBase* theGroup) { myGroups.push_back(theGroup); } + void SetRenumber( bool renumber ) { myRenumber = renumber; } private: TGroupList myGroups; + bool myRenumber; }; diff --git a/src/MEDWrapper/CMakeLists.txt b/src/MEDWrapper/CMakeLists.txt index 7c3478e24..2e8a32fb6 100644 --- a/src/MEDWrapper/CMakeLists.txt +++ b/src/MEDWrapper/CMakeLists.txt @@ -24,6 +24,7 @@ INCLUDE_DIRECTORIES( ${HDF5_INCLUDE_DIRS} ${MEDFILE_INCLUDE_DIRS} ${KERNEL_INCLUDE_DIRS} + ${MEDCOUPLING_INCLUDE_DIRS} ) # additional preprocessor / compiler flags @@ -37,6 +38,7 @@ SET(_link_LIBRARIES ${HDF5_LIBS} ${MEDFILE_C_LIBRARIES} ${KERNEL_SALOMELocalTrace} + ${MEDCoupling_medloader} ) # --- headers --- diff --git a/src/MEDWrapper/MED_Factory.cxx b/src/MEDWrapper/MED_Factory.cxx index e8c145f8c..72f080ca2 100644 --- a/src/MEDWrapper/MED_Factory.cxx +++ b/src/MEDWrapper/MED_Factory.cxx @@ -183,10 +183,10 @@ namespace MED if (!CheckCompatibility(fileName)) { EXCEPTION(std::runtime_error, "Cannot open file '"< versionsOK(GetMEDVersionsAppendCompatible()); - bool isVersionRequestedOK(std::find(versionsOK.begin(),versionsOK.end(),theVersion)!=versionsOK.end()); + std::vector versionsOK = GetMEDVersionsAppendCompatible(); + bool isVersionRequestedOK = std::find(versionsOK.begin(),versionsOK.end(),theVersion)!=versionsOK.end(); if (isCreated && isVersionRequestedOK) { - wantedMajor = theVersion/10; - wantedMinor = theVersion%10; + wantedMajor = theVersion / 10; + wantedMinor = theVersion % 10; } - return new MED::TWrapper(fileName, true, wantedMajor, wantedMinor); + return new MED::TWrapper(fileName, true, tfileInst, wantedMajor, wantedMinor); } } diff --git a/src/MEDWrapper/MED_Factory.hxx b/src/MEDWrapper/MED_Factory.hxx index 6a8c73454..0a2e4efce 100644 --- a/src/MEDWrapper/MED_Factory.hxx +++ b/src/MEDWrapper/MED_Factory.hxx @@ -47,7 +47,7 @@ namespace MED PWrapper CrWrapperR( const std::string& ); MEDWRAPPER_EXPORT - PWrapper CrWrapperW( const std::string&, int theVersion=-1 ); + PWrapper CrWrapperW( const std::string&, int theVersion=-1 , TFileInternal *tfileInst=nullptr ); } #endif // MED_Factory_HeaderFile diff --git a/src/MEDWrapper/MED_Structures.cxx b/src/MEDWrapper/MED_Structures.cxx index bca82e0ff..c04113bc4 100644 --- a/src/MEDWrapper/MED_Structures.cxx +++ b/src/MEDWrapper/MED_Structures.cxx @@ -141,7 +141,8 @@ namespace MED TElemInfo ::SetElemNum(TInt theId, TInt theVal) { - (*myElemNum)[theId] = theVal; + if ( IsElemNum() ) + (*myElemNum)[theId] = theVal; } //--------------------------------------------------------------- diff --git a/src/MEDWrapper/MED_TFile.hxx b/src/MEDWrapper/MED_TFile.hxx new file mode 100644 index 000000000..09634f891 --- /dev/null +++ b/src/MEDWrapper/MED_TFile.hxx @@ -0,0 +1,97 @@ +// Copyright (C) 2021 CEA/DEN, EDF R&D +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +#pragma once + +#include "MED_Wrapper.hxx" +#include "MED_WrapperDef.hxx" + +namespace MED +{ + class TFileInternal + { + public: + virtual ~TFileInternal() = default; + virtual void Open(EModeAcces theMode, TErr* theErr = nullptr) = 0; + virtual void Close() = 0; + virtual const TIdt& Id() const = 0; + }; + + class MEDWRAPPER_EXPORT MEDIDTHoder : public TFileInternal + { + protected: + MEDIDTHoder(bool *isClosedStatus = nullptr):_isClosedStatus(isClosedStatus) { } + void UnRefFid() + { + if (--myCount == 0) + { + MEDfileClose(myFid); + myIsClosed = true; + if(_isClosedStatus) + *_isClosedStatus = true; + } + } + public: + const TIdt& Id() const override; + ~MEDIDTHoder() { this->UnRefFid(); } + void Close() override { this->UnRefFid(); } + protected: + TInt myCount = 0; + TIdt myFid = 0; + bool myIsClosed = false; + bool *_isClosedStatus = nullptr; + }; + + class MEDWRAPPER_EXPORT TFileDecorator : public TFileInternal + { + public: + TFileDecorator(TFileInternal *effective):_effective(effective) { } + void Open(EModeAcces theMode, TErr* theErr = nullptr) override { if(_effective) _effective->Open(theMode,theErr); } + void Close() override { if(_effective) _effective->Close(); } + const TIdt& Id() const override { if(_effective) return _effective->Id(); EXCEPTION(std::runtime_error, "TFileDecorator - GetFid() : no effective TFile !"); } + ~TFileDecorator() { delete _effective; } + private: + TFileInternal *_effective = nullptr; + }; + + class MEDWRAPPER_EXPORT TMemFile : public MEDIDTHoder + { + public: + TMemFile(void **data, std::size_t *sz, bool* isClosedStatus):MEDIDTHoder(isClosedStatus),_data(data),_sz(sz) { memfile.app_image_ptr=*data; memfile.app_image_size=*sz; } + ~TMemFile() { UnRefFid(); if(myIsClosed) { *_data = memfile.app_image_ptr; *_sz = memfile.app_image_size; } } + void Open(EModeAcces theMode, TErr* theErr = nullptr) override; + void *getData() const { return memfile.app_image_ptr; } + std::size_t getSize() const { return memfile.app_image_size; } + private: + void **_data = nullptr; + std::size_t * _sz = nullptr; + med_memfile memfile = MED_MEMFILE_INIT; + }; + + class MEDWRAPPER_EXPORT TFile : public MEDIDTHoder + { + public: + TFile(const std::string& theFileName, TInt theMajor=-1, TInt theMinor=-1); + void Open(EModeAcces theMode, TErr* theErr = nullptr) override; + protected: + std::string myFileName; + TInt myMajor; + TInt myMinor; + }; +} diff --git a/src/MEDWrapper/MED_TStructures.hxx b/src/MEDWrapper/MED_TStructures.hxx index 3c3092d00..3197b6b6d 100644 --- a/src/MEDWrapper/MED_TStructures.hxx +++ b/src/MEDWrapper/MED_TStructures.hxx @@ -204,10 +204,10 @@ namespace MED } } - TTFamilyInfo(const PMeshInfo& theMeshInfo, - TInt theNbGroup, - TInt theNbAttr, - TInt theId, + TTFamilyInfo(const PMeshInfo& theMeshInfo, + TInt theNbGroup, + TInt theNbAttr, + TInt theId, const std::string& theValue): TNameInfoBase(theValue) { @@ -224,13 +224,13 @@ namespace MED myAttrDesc.resize(theNbAttr*GetDESCLength()+1); } - TTFamilyInfo(const PMeshInfo& theMeshInfo, - const std::string& theValue, - TInt theId, - const TStringSet& theGroupNames, - const TStringVector& theAttrDescs, - const TIntVector& theAttrIds, - const TIntVector& theAttrVals): + TTFamilyInfo(const PMeshInfo& theMeshInfo, + const std::string& theValue, + TInt theId, + const TStringSet& theGroupNames, + const TStringVector& theAttrDescs, + const TIntVector& theAttrIds, + const TIntVector& theAttrVals): TNameInfoBase(theValue) { myMeshInfo = theMeshInfo; @@ -262,8 +262,8 @@ namespace MED virtual std::string - GetGroupName(TInt theId) const - { + GetGroupName(TInt theId) const + { return GetString(theId, GetLNOMLength(), myGroupNames); } @@ -329,10 +329,10 @@ namespace MED } } - TTElemInfo(const PMeshInfo& theMeshInfo, - TInt theNbElem, - EBooleen theIsElemNum, - EBooleen theIsElemNames) + TTElemInfo(const PMeshInfo& theMeshInfo, + TInt theNbElem, + EBooleen theIsElemNum, + EBooleen theIsElemNames) { myMeshInfo = theMeshInfo; @@ -351,26 +351,26 @@ namespace MED myElemNames.reset(new TString(theNbElem*GetPNOMLength() + 1)); else myElemNames.reset(new TString()); - } - - TTElemInfo(const PMeshInfo& theMeshInfo, - TInt theNbElem, - const TIntVector& theFamilyNums, - const TIntVector& theElemNums, + } + + TTElemInfo(const PMeshInfo& theMeshInfo, + TInt theNbElem, + const TIntVector& theFamilyNums, + const TIntVector& theElemNums, const TStringVector& theElemNames) { myMeshInfo = theMeshInfo; - + myNbElem = theNbElem; myFamNum.reset(new TElemNum(theNbElem)); myIsFamNum = eFAUX; // is set to eVRAI in SetFamNum() - + myIsElemNum = theElemNums.size()? eVRAI: eFAUX; if(myIsElemNum) myElemNum.reset(new TElemNum(theNbElem)); else myElemNum.reset(new TElemNum()); - + myIsElemNames = theElemNames.size()? eVRAI: eFAUX; if(myIsElemNames) myElemNames.reset(new TString(theNbElem*GetPNOMLength() + 1)); @@ -671,7 +671,7 @@ namespace MED myEntity = theInfo->GetEntity(); myGeom = theInfo->GetGeom(); myConnMode = theInfo->GetConnMode(); - + TInt aConnDim = GetNbNodes(myGeom); TInt aNbConn = GetNbConn(myGeom, myEntity, myMeshInfo->myDim); myConn.reset(new TElemNum(myNbElem * aNbConn)); @@ -684,14 +684,14 @@ namespace MED } } - TTCellInfo(const PMeshInfo& theMeshInfo, - EEntiteMaillage theEntity, + TTCellInfo(const PMeshInfo& theMeshInfo, + EEntiteMaillage theEntity, EGeometrieElement theGeom, - TInt theNbElem, - EConnectivite theConnMode, - EBooleen theIsElemNum, - EBooleen theIsElemNames, - EModeSwitch theMode): + TInt theNbElem, + EConnectivite theConnMode, + EBooleen theIsElemNum, + EBooleen theIsElemNames, + EModeSwitch theMode): TModeSwitchInfo(theMode), TElemInfoBase(theMeshInfo, theNbElem, @@ -705,16 +705,16 @@ namespace MED TInt aNbConn = GetNbConn(theGeom, myEntity, theMeshInfo->myDim); myConn.reset(new TElemNum(theNbElem * aNbConn)); } - - TTCellInfo(const PMeshInfo& theMeshInfo, - EEntiteMaillage theEntity, - EGeometrieElement theGeom, - const TIntVector& theConnectivities, - EConnectivite theConnMode, - const TIntVector& theFamilyNums, - const TIntVector& theElemNums, + + TTCellInfo(const PMeshInfo& theMeshInfo, + EEntiteMaillage theEntity, + EGeometrieElement theGeom, + const TIntVector& theConnectivities, + EConnectivite theConnMode, + const TIntVector& theFamilyNums, + const TIntVector& theElemNums, const TStringVector& theElemNames, - EModeSwitch theMode): + EModeSwitch theMode): TModeSwitchInfo(theMode), TElemInfoBase(theMeshInfo, (TInt)theConnectivities.size() / GetNbNodes(theGeom), @@ -737,10 +737,10 @@ namespace MED } } - virtual + virtual TInt - GetConnDim() const - { + GetConnDim() const + { return GetNbConn(myGeom, myEntity, myMeshInfo->myDim); } @@ -779,7 +779,7 @@ namespace MED myDiameters.resize( theNbElem ); } - TTBallInfo(const PMeshInfo& theMeshInfo, + TTBallInfo(const PMeshInfo& theMeshInfo, const TIntVector& theNodes, TFloatVector& theDiameters, const TIntVector& theFamilyNums, @@ -804,8 +804,8 @@ namespace MED }; //--------------------------------------------------------------- - struct TTFieldInfo: - virtual TFieldInfo, + struct TTFieldInfo: + virtual TFieldInfo, virtual TTNameInfo { typedef TTNameInfo TNameInfoBase; @@ -832,12 +832,12 @@ namespace MED myNbRef = theInfo->GetNbRef(); } - TTFieldInfo(const PMeshInfo& theMeshInfo, - TInt theNbComp, - ETypeChamp theType, + TTFieldInfo(const PMeshInfo& theMeshInfo, + TInt theNbComp, + ETypeChamp theType, const std::string& theValue, - EBooleen theIsLocal, - TInt theNbRef): + EBooleen theIsLocal, + TInt theNbRef): TNameInfoBase(theValue) { myMeshInfo = theMeshInfo; @@ -925,15 +925,15 @@ namespace MED myGeom2Gauss = theInfo->GetGeom2Gauss(); } - TTTimeStampInfo(const PFieldInfo& theFieldInfo, - EEntiteMaillage theEntity, - const TGeom2Size& theGeom2Size, + TTTimeStampInfo(const PFieldInfo& theFieldInfo, + EEntiteMaillage theEntity, + const TGeom2Size& theGeom2Size, const TGeom2NbGauss& theGeom2NbGauss, - TInt theNumDt, - TInt /*theNumOrd*/, - TFloat theDt, - const std::string& theUnitDt, - const TGeom2Gauss& theGeom2Gauss) + TInt theNumDt, + TInt /*theNumOrd*/, + TFloat theDt, + const std::string& theUnitDt, + const TGeom2Gauss& theGeom2Gauss) { myFieldInfo = theFieldInfo; @@ -951,10 +951,10 @@ namespace MED myGeom2Gauss = theGeom2Gauss; } - virtual + virtual std::string GetUnitDt() const - { + { return GetString(0,GetPNOMLength(),myUnitDt); } @@ -974,7 +974,7 @@ namespace MED typedef TTNameInfo TNameInfoBase; TTProfileInfo(const TProfileInfo::TInfo& theInfo, - EModeProfil theMode): + EModeProfil theMode): TNameInfoBase(boost::get<0>(theInfo)) { TInt aSize = boost::get<1>(theInfo); @@ -987,9 +987,9 @@ namespace MED template struct TTTimeStampValue: virtual TTimeStampValue { - TTTimeStampValue(const PTimeStampInfo& theTimeStampInfo, + TTTimeStampValue(const PTimeStampInfo& theTimeStampInfo, const PTimeStampValueBase& theInfo, - ETypeChamp theTypeChamp) + ETypeChamp theTypeChamp) { typedef TTimeStampValue TCompatible; if(TCompatible* aCompatible = dynamic_cast(theInfo.get())){ @@ -1003,9 +1003,9 @@ namespace MED } TTTimeStampValue(const PTimeStampInfo& theTimeStampInfo, - ETypeChamp theTypeChamp, - const TGeom2Profile& theGeom2Profile, - EModeSwitch theMode): + ETypeChamp theTypeChamp, + const TGeom2Profile& theGeom2Profile, + EModeSwitch theMode): TModeSwitchInfo(theMode) { this->myTimeStampInfo = theTimeStampInfo; @@ -1031,44 +1031,44 @@ namespace MED aNbElem = aProfileInfo->GetSize(); TInt aNbGauss = theTimeStampInfo->GetNbGauss(aGeom); - + this->GetMeshValue(aGeom).Allocate(aNbElem,aNbGauss,aNbComp); } } - virtual + virtual size_t GetValueSize(EGeometrieElement theGeom) const { return this->GetMeshValue(theGeom).GetSize(); } - virtual + virtual size_t GetNbVal(EGeometrieElement theGeom) const { return this->GetMeshValue(theGeom).GetNbVal(); } - virtual + virtual size_t GetNbGauss(EGeometrieElement theGeom) const { return this->GetMeshValue(theGeom).GetNbGauss(); } - virtual + virtual void AllocateValue(EGeometrieElement theGeom, - TInt theNbElem, - TInt theNbGauss, - TInt theNbComp, - EModeSwitch theMode = eFULL_INTERLACE) + TInt theNbElem, + TInt theNbGauss, + TInt theNbComp, + EModeSwitch theMode = eFULL_INTERLACE) { this->GetMeshValue(theGeom).Allocate(theNbElem,theNbGauss,theNbComp,theMode); } - - virtual + + virtual unsigned char* GetValuePtr(EGeometrieElement theGeom) { @@ -1080,13 +1080,13 @@ namespace MED struct TTGrilleInfo: virtual TGrilleInfo { - TTGrilleInfo(const PMeshInfo& theMeshInfo, + TTGrilleInfo(const PMeshInfo& theMeshInfo, const PGrilleInfo& theInfo) { myMeshInfo = theMeshInfo; myCoord = theInfo->GetNodeCoord(); - + myGrilleType = theInfo->GetGrilleType(); myCoordNames = theInfo->myCoordNames; @@ -1105,9 +1105,9 @@ namespace MED myFamNum = theInfo->myFamNum; } - TTGrilleInfo(const PMeshInfo& theMeshInfo, + TTGrilleInfo(const PMeshInfo& theMeshInfo, const EGrilleType& type, - const TInt nnoeuds) + const TInt nnoeuds) { myMeshInfo = theMeshInfo; TInt aSpaceDim = theMeshInfo->GetSpaceDim(); @@ -1123,7 +1123,7 @@ namespace MED myFamNumNode.resize(nnoeuds); } - TTGrilleInfo(const PMeshInfo& theMeshInfo, + TTGrilleInfo(const PMeshInfo& theMeshInfo, const EGrilleType& type) { myMeshInfo = theMeshInfo; @@ -1138,8 +1138,8 @@ namespace MED myGrilleStructure.resize(aSpaceDim); } - TTGrilleInfo(const PMeshInfo& theMeshInfo, - const EGrilleType& type, + TTGrilleInfo(const PMeshInfo& theMeshInfo, + const EGrilleType& type, const MED::TIntVector& nbNodeVec) { myMeshInfo = theMeshInfo; @@ -1175,9 +1175,9 @@ namespace MED } virtual - std::string - GetCoordUnit(TInt theId) const - { + std::string + GetCoordUnit(TInt theId) const + { return GetString(theId,GetPNOMLength(),myCoordUnits); } diff --git a/src/MEDWrapper/MED_Wrapper.cxx b/src/MEDWrapper/MED_Wrapper.cxx index f4a7fc458..b0c56200e 100644 --- a/src/MEDWrapper/MED_Wrapper.cxx +++ b/src/MEDWrapper/MED_Wrapper.cxx @@ -23,7 +23,9 @@ #include "MED_Wrapper.hxx" #include "MED_TStructures.hxx" #include "MED_Utilities.hxx" +#include "MED_TFile.hxx" +#include "MEDFileUtilities.hxx" #include #include #include @@ -76,93 +78,78 @@ namespace MED } //--------------------------------------------------------------- - class TFile + const TIdt& MEDIDTHoder::Id() const { - TFile(); - TFile(const TFile&); + if (myFid < 0) + EXCEPTION(std::runtime_error, "TFile - GetFid() < 0"); + return myFid; + } - public: - TFile(const std::string& theFileName, TInt theMajor=-1, TInt theMinor=-1): - myCount(0), - myFid(0), - myFileName(theFileName), - myMajor(theMajor), - myMinor(theMinor) + void TMemFile::Open(EModeAcces theMode, TErr* theErr) + { + if (this->myCount++ == 0) { - if ((myMajor < 0) || (myMajor > MED_MAJOR_NUM)) myMajor = MED_MAJOR_NUM; - if ((myMinor < 0) || (myMajor == MED_MAJOR_NUM && myMinor > MED_MINOR_NUM)) myMinor = MED_MINOR_NUM; + std::string dftFileName = MEDCoupling::MEDFileWritableStandAlone::GenerateUniqueDftFileNameInMem(); + med_access_mode modeTmp(MED_ACC_CREAT); + if(memfile.app_image_ptr) + modeTmp = med_access_mode(theMode); + myFid = MEDmemFileOpen(dftFileName.c_str(),&memfile,MED_FALSE,modeTmp); } + if (theErr) + *theErr = TErr(myFid); + else if (myFid < 0) + EXCEPTION(std::runtime_error,"TMemFile - MEDmemFileOpen"); + } - ~TFile() - { - Close(); - } + TFile::TFile(const std::string& theFileName, TInt theMajor, TInt theMinor): + myFileName(theFileName), + myMajor(theMajor), + myMinor(theMinor) + { + if ((myMajor < 0) || (myMajor > MED_MAJOR_NUM)) myMajor = MED_MAJOR_NUM; + if ((myMinor < 0) || (myMajor == MED_MAJOR_NUM && myMinor > MED_MINOR_NUM)) myMinor = MED_MINOR_NUM; + } - void - Open(EModeAcces theMode, - TErr* theErr = NULL) - { - if (myCount++ == 0) { - const char* aFileName = myFileName.c_str(); + void TFile::Open(EModeAcces theMode, TErr* theErr) + { + if (myCount++ == 0) { + const char* aFileName = myFileName.c_str(); #ifdef WIN32 - if (med_access_mode(theMode) == MED_ACC_RDWR) { - // Force removing readonly attribute from a file under Windows, because of a bug in the HDF5 - std::string aReadOlnyRmCmd = "attrib -r \"" + myFileName + "\"> nul 2>&1"; + if (med_access_mode(theMode) == MED_ACC_RDWR) { + // Force removing readonly attribute from a file under Windows, because of a bug in the HDF5 + std::string aReadOlnyRmCmd = "attrib -r \"" + myFileName + "\"> nul 2>&1"; #ifdef UNICODE - const char* to_decode = aReadOlnyRmCmd.c_str(); - int size_needed = MultiByteToWideChar(CP_UTF8, 0, to_decode, strlen(to_decode), NULL, 0); - wchar_t* awReadOlnyRmCmd = new wchar_t[size_needed + 1]; - MultiByteToWideChar(CP_UTF8, 0, to_decode, strlen(to_decode), awReadOlnyRmCmd, size_needed); - awReadOlnyRmCmd[size_needed] = '\0'; - _wsystem(awReadOlnyRmCmd); - delete[] awReadOlnyRmCmd; + const char* to_decode = aReadOlnyRmCmd.c_str(); + int size_needed = MultiByteToWideChar(CP_UTF8, 0, to_decode, strlen(to_decode), NULL, 0); + wchar_t* awReadOlnyRmCmd = new wchar_t[size_needed + 1]; + MultiByteToWideChar(CP_UTF8, 0, to_decode, strlen(to_decode), awReadOlnyRmCmd, size_needed); + awReadOlnyRmCmd[size_needed] = '\0'; + _wsystem(awReadOlnyRmCmd); + delete[] awReadOlnyRmCmd; #else - system(aReadOlnyRmCmd.c_str()); + system(aReadOlnyRmCmd.c_str()); #endif - } -#endif - myFid = MEDfileVersionOpen(aFileName,med_access_mode(theMode), myMajor, myMinor, MED_RELEASE_NUM); } - if (theErr) - *theErr = TErr(myFid); - else if (myFid < 0) - EXCEPTION(std::runtime_error,"TFile - MEDfileVersionOpen('"<Open(eLECTURE_ECRITURE, &aRet); @@ -251,9 +242,9 @@ namespace MED //---------------------------------------------------------------------------- void TWrapper - ::GetMeshInfo(TInt theMeshId, + ::GetMeshInfo(TInt theMeshId, MED::TMeshInfo& theInfo, - TErr* theErr) + TErr* theErr) { TFileWrapper aFileWrapper(myFile, eLECTURE, theErr, myMinor); @@ -294,7 +285,7 @@ namespace MED void TWrapper ::SetMeshInfo(const MED::TMeshInfo& theInfo, - TErr* theErr) + TErr* theErr) { TErr aRet; SetMeshInfo(theInfo, eLECTURE_ECRITURE, &aRet); @@ -313,8 +304,8 @@ namespace MED void TWrapper ::SetMeshInfo(const MED::TMeshInfo& theInfo, - EModeAcces theMode, - TErr* theErr) + EModeAcces theMode, + TErr* theErr) { TFileWrapper aFileWrapper(myFile, theMode, theErr, myMinor); @@ -361,10 +352,10 @@ namespace MED //---------------------------------------------------------------------------- PMeshInfo TWrapper - ::CrMeshInfo(TInt theDim, - TInt theSpaceDim, + ::CrMeshInfo(TInt theDim, + TInt theSpaceDim, const std::string& theValue, - EMaillage theType, + EMaillage theType, const std::string& theDesc) { return PMeshInfo(new TTMeshInfo @@ -386,7 +377,7 @@ namespace MED //---------------------------------------------------------------------------- PMeshInfo TWrapper - ::GetPMeshInfo(TInt theId, + ::GetPMeshInfo(TInt theId, TErr* theErr) { PMeshInfo anInfo = CrMeshInfo(); @@ -398,7 +389,7 @@ namespace MED TInt TWrapper ::GetNbFamilies(const MED::TMeshInfo& theInfo, - TErr* theErr) + TErr* theErr) { TFileWrapper aFileWrapper(myFile, eLECTURE, theErr, myMinor); @@ -413,9 +404,9 @@ namespace MED //---------------------------------------------------------------------------- TInt TWrapper - ::GetNbFamAttr(TInt theFamId, + ::GetNbFamAttr(TInt theFamId, const MED::TMeshInfo& theInfo, - TErr* theErr) + TErr* theErr) { TFileWrapper aFileWrapper(myFile, eLECTURE, theErr, myMinor); @@ -432,9 +423,9 @@ namespace MED //---------------------------------------------------------------------------- TInt TWrapper - ::GetNbFamGroup(TInt theFamId, + ::GetNbFamGroup(TInt theFamId, const MED::TMeshInfo& theInfo, - TErr* theErr) + TErr* theErr) { TFileWrapper aFileWrapper(myFile, eLECTURE, theErr, myMinor); @@ -451,9 +442,9 @@ namespace MED //---------------------------------------------------------------------------- void TWrapper - ::GetFamilyInfo(TInt theFamId, + ::GetFamilyInfo(TInt theFamId, MED::TFamilyInfo& theInfo, - TErr* theErr) + TErr* theErr) { TFileWrapper aFileWrapper(myFile, eLECTURE, theErr, myMinor); @@ -494,7 +485,7 @@ namespace MED void TWrapper ::SetFamilyInfo(const MED::TFamilyInfo& theInfo, - TErr* theErr) + TErr* theErr) { TErr aRet; SetFamilyInfo(theInfo, eLECTURE_ECRITURE, &aRet); @@ -510,8 +501,8 @@ namespace MED void TWrapper ::SetFamilyInfo(const MED::TFamilyInfo& theInfo, - EModeAcces theMode, - TErr* theErr) + EModeAcces theMode, + TErr* theErr) { TFileWrapper aFileWrapper(myFile, theMode, theErr, myMinor); @@ -549,10 +540,10 @@ namespace MED //---------------------------------------------------------------------------- PFamilyInfo TWrapper - ::CrFamilyInfo(const PMeshInfo& theMeshInfo, - TInt theNbGroup, - TInt theNbAttr, - TInt theId, + ::CrFamilyInfo(const PMeshInfo& theMeshInfo, + TInt theNbGroup, + TInt theNbAttr, + TInt theId, const std::string& theValue) { return PFamilyInfo(new TTFamilyInfo @@ -566,13 +557,13 @@ namespace MED //---------------------------------------------------------------------------- PFamilyInfo TWrapper - ::CrFamilyInfo(const PMeshInfo& theMeshInfo, - const std::string& theValue, - TInt theId, - const MED::TStringSet& theGroupNames, + ::CrFamilyInfo(const PMeshInfo& theMeshInfo, + const std::string& theValue, + TInt theId, + const MED::TStringSet& theGroupNames, const MED::TStringVector& theAttrDescs, - const MED::TIntVector& theAttrIds, - const MED::TIntVector& theAttrVals) + const MED::TIntVector& theAttrIds, + const MED::TIntVector& theAttrVals) { return PFamilyInfo(new TTFamilyInfo (theMeshInfo, @@ -587,7 +578,7 @@ namespace MED //---------------------------------------------------------------------------- PFamilyInfo TWrapper - ::CrFamilyInfo(const PMeshInfo& theMeshInfo, + ::CrFamilyInfo(const PMeshInfo& theMeshInfo, const PFamilyInfo& theInfo) { return PFamilyInfo(new TTFamilyInfo @@ -599,8 +590,8 @@ namespace MED PFamilyInfo TWrapper ::GetPFamilyInfo(const PMeshInfo& theMeshInfo, - TInt theId, - TErr* theErr) + TInt theId, + TErr* theErr) { // must be reimplemented in connection with mesh type eSTRUCTURE // if (theMeshInfo->GetType() != eNON_STRUCTURE) @@ -629,11 +620,11 @@ namespace MED //---------------------------------------------------------------------------- void TWrapper - ::GetNames(TElemInfo& theInfo, - TInt /*theNb*/, - EEntiteMaillage theEntity, + ::GetNames(TElemInfo& theInfo, + TInt /*theNb*/, + EEntiteMaillage theEntity, EGeometrieElement theGeom, - TErr* theErr) + TErr* theErr) { TFileWrapper aFileWrapper(myFile, eLECTURE, theErr, myMinor); @@ -667,10 +658,10 @@ namespace MED //---------------------------------------------------------------------------- void TWrapper - ::SetNames(const TElemInfo& theInfo, - EEntiteMaillage theEntity, + ::SetNames(const TElemInfo& theInfo, + EEntiteMaillage theEntity, EGeometrieElement theGeom, - TErr* theErr) + TErr* theErr) { SetNames(theInfo, eLECTURE_ECRITURE, theEntity, theGeom, theErr); } @@ -678,11 +669,11 @@ namespace MED //---------------------------------------------------------------------------- void TWrapper - ::SetNames(const TElemInfo& theInfo, - EModeAcces theMode, - EEntiteMaillage theEntity, + ::SetNames(const TElemInfo& theInfo, + EModeAcces theMode, + EEntiteMaillage theEntity, EGeometrieElement theGeom, - TErr* theErr) + TErr* theErr) { TFileWrapper aFileWrapper(myFile, theMode, theErr, myMinor); @@ -707,7 +698,7 @@ namespace MED MED_NO_DT, MED_NO_IT, anEntity, - aGeom, + aGeom, (TInt)anInfo.myElemNames->size(), &anElemNames); if (theErr) @@ -720,11 +711,11 @@ namespace MED //---------------------------------------------------------------------------- void TWrapper - ::GetNumeration(TElemInfo& theInfo, - TInt /*theNb*/, - EEntiteMaillage theEntity, + ::GetNumeration(TElemInfo& theInfo, + TInt /*theNb*/, + EEntiteMaillage theEntity, EGeometrieElement theGeom, - TErr* theErr) + TErr* theErr) { TFileWrapper aFileWrapper(myFile, eLECTURE, theErr, myMinor); @@ -758,10 +749,10 @@ namespace MED //---------------------------------------------------------------------------- void TWrapper - ::SetNumeration(const TElemInfo& theInfo, - EEntiteMaillage theEntity, + ::SetNumeration(const TElemInfo& theInfo, + EEntiteMaillage theEntity, EGeometrieElement theGeom, - TErr* theErr) + TErr* theErr) { SetNumeration(theInfo, eLECTURE_ECRITURE, theEntity, theGeom, theErr); } @@ -769,11 +760,11 @@ namespace MED //---------------------------------------------------------------------------- void TWrapper - ::SetNumeration(const TElemInfo& theInfo, - EModeAcces theMode, - EEntiteMaillage theEntity, + ::SetNumeration(const TElemInfo& theInfo, + EModeAcces theMode, + EEntiteMaillage theEntity, EGeometrieElement theGeom, - TErr* theErr) + TErr* theErr) { TFileWrapper aFileWrapper(myFile, theMode, theErr, myMinor); @@ -811,11 +802,11 @@ namespace MED //---------------------------------------------------------------------------- void TWrapper - ::GetFamilies(TElemInfo& theInfo, - TInt /*theNb*/, - EEntiteMaillage theEntity, + ::GetFamilies(TElemInfo& theInfo, + TInt /*theNb*/, + EEntiteMaillage theEntity, EGeometrieElement theGeom, - TErr* theErr) + TErr* theErr) { TFileWrapper aFileWrapper(myFile, eLECTURE, theErr, myMinor); @@ -858,10 +849,10 @@ namespace MED //---------------------------------------------------------------------------- void TWrapper - ::SetFamilies(const TElemInfo& theInfo, - EEntiteMaillage theEntity, + ::SetFamilies(const TElemInfo& theInfo, + EEntiteMaillage theEntity, EGeometrieElement theGeom, - TErr* theErr) + TErr* theErr) { SetFamilies(theInfo, eLECTURE_ECRITURE, theEntity, theGeom, theErr); } @@ -869,11 +860,11 @@ namespace MED //---------------------------------------------------------------------------- void TWrapper - ::SetFamilies(const TElemInfo& theInfo, - EModeAcces theMode, - EEntiteMaillage theEntity, + ::SetFamilies(const TElemInfo& theInfo, + EModeAcces theMode, + EEntiteMaillage theEntity, EGeometrieElement theGeom, - TErr* theErr) + TErr* theErr) { TFileWrapper aFileWrapper(myFile, theMode, theErr, myMinor); @@ -910,7 +901,7 @@ namespace MED TInt TWrapper ::GetNbNodes(const MED::TMeshInfo& theMeshInfo, - TErr* theErr) + TErr* theErr) { return GetNbNodes(theMeshInfo, eCOOR, theErr); } @@ -2217,14 +2208,14 @@ namespace MED //---------------------------------------------------------------------------- PCellInfo TWrapper - ::CrCellInfo(const PMeshInfo& theMeshInfo, - EEntiteMaillage theEntity, + ::CrCellInfo(const PMeshInfo& theMeshInfo, + EEntiteMaillage theEntity, EGeometrieElement theGeom, - TInt theNbElem, - EConnectivite theConnMode, - EBooleen theIsElemNum, - EBooleen theIsElemNames, - EModeSwitch theMode) + TInt theNbElem, + EConnectivite theConnMode, + EBooleen theIsElemNum, + EBooleen theIsElemNames, + EModeSwitch theMode) { return PCellInfo(new TTCellInfo (theMeshInfo, diff --git a/src/MEDWrapper/MED_Wrapper.hxx b/src/MEDWrapper/MED_Wrapper.hxx index bc73c9dd9..ddd3a159b 100644 --- a/src/MEDWrapper/MED_Wrapper.hxx +++ b/src/MEDWrapper/MED_Wrapper.hxx @@ -32,8 +32,8 @@ namespace MED { //---------------------------------------------------------------------------- - class TFile; - typedef boost::shared_ptr PFile; + class TFileInternal; + typedef std::shared_ptr PFileInternal; typedef enum {eLECTURE, eLECTURE_ECRITURE, eLECTURE_AJOUT, eCREATION} EModeAcces; @@ -52,7 +52,7 @@ namespace MED TWrapper& operator=(const TWrapper&); public: - TWrapper(const std::string& theFileName, bool write, TInt theMajor=-1, TInt theVersion=-1); + TWrapper(const std::string& theFileName, bool write, TFileInternal *tfileInst = nullptr, TInt theMajor=-1, TInt theVersion=-1); virtual ~TWrapper(); @@ -938,7 +938,7 @@ namespace MED TErr* theErr = NULL); protected: - PFile myFile; + PFileInternal myFile; TInt myMajor; TInt myMinor; }; @@ -963,23 +963,23 @@ namespace MED //---------------------------------------------------------------------------- //! Specialization of SharedPtr for TWrapper template<> - class MEDWRAPPER_EXPORT SharedPtr: public boost::shared_ptr + class MEDWRAPPER_EXPORT SharedPtr: public std::shared_ptr { public: SharedPtr() {} SharedPtr(TWrapper* p): - boost::shared_ptr(p) + std::shared_ptr(p) {} template explicit SharedPtr(Y* p): - boost::shared_ptr(p) + std::shared_ptr(p) {} template SharedPtr(const SharedPtr& r): - boost::shared_ptr(boost::dynamic_pointer_cast(r)) + std::shared_ptr(boost::dynamic_pointer_cast(r)) {} template @@ -1021,7 +1021,7 @@ namespace MED TWrapper* get() const // never throws { - return boost::shared_ptr::get(); + return std::shared_ptr::get(); } }; } diff --git a/src/OBJECT/SMESH_ActorUtils.cxx b/src/OBJECT/SMESH_ActorUtils.cxx index f79f01ae8..203f7931b 100644 --- a/src/OBJECT/SMESH_ActorUtils.cxx +++ b/src/OBJECT/SMESH_ActorUtils.cxx @@ -157,17 +157,17 @@ namespace SMESH } } - std::map GetEntitiesFromObject(SMESH_VisualObj *theObject) { - std::map entities; - entities.insert(std::pair(SMDSAbs_0DElement, + std::map GetEntitiesFromObject(SMESH_VisualObj *theObject) { + std::map entities; + entities.insert(std::pair(SMDSAbs_0DElement, theObject ? theObject->GetNbEntities(SMDSAbs_0DElement) : 0)); - entities.insert(std::pair(SMDSAbs_Ball, + entities.insert(std::pair(SMDSAbs_Ball, theObject ? theObject->GetNbEntities(SMDSAbs_Ball) : 0)); - entities.insert(std::pair(SMDSAbs_Edge, + entities.insert(std::pair(SMDSAbs_Edge, theObject ? theObject->GetNbEntities(SMDSAbs_Edge) : 0)); - entities.insert(std::pair(SMDSAbs_Face, + entities.insert(std::pair(SMDSAbs_Face, theObject ? theObject->GetNbEntities(SMDSAbs_Face) : 0)); - entities.insert(std::pair(SMDSAbs_Volume, + entities.insert(std::pair(SMDSAbs_Volume, theObject ? theObject->GetNbEntities(SMDSAbs_Volume) : 0)); return entities; } diff --git a/src/OBJECT/SMESH_ActorUtils.h b/src/OBJECT/SMESH_ActorUtils.h index a6ea963a5..4167e5ae1 100644 --- a/src/OBJECT/SMESH_ActorUtils.h +++ b/src/OBJECT/SMESH_ActorUtils.h @@ -84,7 +84,7 @@ SMESHOBJECT_EXPORT QString def); SMESHOBJECT_EXPORT - std::map + std::map GetEntitiesFromObject(SMESH_VisualObj *theObject); SMESHOBJECT_EXPORT diff --git a/src/OBJECT/SMESH_Object.cxx b/src/OBJECT/SMESH_Object.cxx index 6f8551d09..846c81562 100644 --- a/src/OBJECT/SMESH_Object.cxx +++ b/src/OBJECT/SMESH_Object.cxx @@ -557,7 +557,7 @@ void SMESH_VisualObjDef::updateEntitiesFlags() unsigned int tmp = myEntitiesState; ClearEntitiesFlags(); - map entities = SMESH::GetEntitiesFromObject(this); + map entities = SMESH::GetEntitiesFromObject(this); if( myEntitiesCache[SMDSAbs_0DElement] != 0 || diff --git a/src/PluginUtils/GeomSelectionTools.h b/src/PluginUtils/GeomSelectionTools.h index 56b3c65a5..e1b8c741e 100644 --- a/src/PluginUtils/GeomSelectionTools.h +++ b/src/PluginUtils/GeomSelectionTools.h @@ -41,9 +41,6 @@ class LightApp_SelectionMgr; /*! * The GeomSelectionTools class gives high level tools to select Geom (and other objects) * A specific attention has been given to analyze selected GEOM objects. - * - * @param myStudy This class is specific to the study ! - * */ class PLUGINUTILS_EXPORT GeomSelectionTools diff --git a/src/SMDS/SMDS_Mesh.cxx b/src/SMDS/SMDS_Mesh.cxx index eaaea6803..2e9924295 100644 --- a/src/SMDS/SMDS_Mesh.cxx +++ b/src/SMDS/SMDS_Mesh.cxx @@ -47,7 +47,8 @@ #include #include -#include +//#include +#include #if !defined WIN32 && !defined __APPLE__ #include @@ -1063,16 +1064,27 @@ bool SMDS_Mesh::ChangePolyhedronNodes(const SMDS_MeshElement * e // keep current nodes of element std::set oldNodes( element->begin_nodes(), element->end_nodes() ); - // change nodes bool Ok = false; + + // change vtkUnstructuredGrid::Faces if ( const SMDS_MeshVolume* vol = DownCast( element )) Ok = vol->ChangeNodes( nodes, quantities ); + // change vtkUnstructuredGrid::Connectivity and inverse connectivity if ( Ok ) - { - setMyModified(); - updateInverseElements( element, &nodes[0], nodes.size(), oldNodes ); - } + if ( SMDS_MeshCell* cell = dynamic_cast((SMDS_MeshElement*) element)) + { + boost::container::flat_set< const SMDS_MeshNode* > uniqueNodes( nodes.begin(), nodes.end() ); + const SMDS_MeshNode** nodesPtr = &( *uniqueNodes.begin()); + const int nbNodes = (int) uniqueNodes.size(); + Ok = cell->ChangeNodes( nodesPtr, nbNodes ); + if ( Ok ) + { + updateInverseElements( element, nodesPtr, nbNodes, oldNodes ); + setMyModified(); + } + } + return Ok; } diff --git a/src/SMDS/SMDS_UnstructuredGrid.cxx b/src/SMDS/SMDS_UnstructuredGrid.cxx index d6b4a2126..124d069f1 100644 --- a/src/SMDS/SMDS_UnstructuredGrid.cxx +++ b/src/SMDS/SMDS_UnstructuredGrid.cxx @@ -1004,14 +1004,14 @@ void SMDS_UnstructuredGrid::ModifyCellNodes(int vtkVolId, std::map loc */ int SMDS_UnstructuredGrid::getOrderedNodesOfFace(int vtkVolId, int& dim, std::vector& orderedNodes) { - int vtkType = this->GetCellType(vtkVolId); - dim = SMDS_Downward::getCellDimension(vtkType); + int vtkType = this->GetCellType( vtkVolId ); + dim = SMDS_Downward::getCellDimension( vtkType ); if (dim == 3) - { - SMDS_Down3D *downvol = static_cast (_downArray[vtkType]); - int downVolId = this->_cellIdToDownId[vtkVolId]; - downvol->getOrderedNodesOfFace(downVolId, orderedNodes); - } + { + SMDS_Down3D *downvol = static_cast (_downArray[vtkType]); + int downVolId = this->_cellIdToDownId[ vtkVolId ]; + downvol->getOrderedNodesOfFace(downVolId, orderedNodes); + } // else nothing to do; return orderedNodes.size(); } @@ -1090,74 +1090,88 @@ SMDS_UnstructuredGrid::extrudeVolumeFromFace(int vtkVolId, break; default: isQuadratic = false; - break; + break; } if (isQuadratic) + { + long dom1 = domain1; + long dom2 = domain2; + long dom1_2; // for nodeQuadDomains + if (domain1 < domain2) + dom1_2 = dom1 + INT_MAX * dom2; + else + dom1_2 = dom2 + INT_MAX * dom1; + //cerr << "dom1=" << dom1 << " dom2=" << dom2 << " dom1_2=" << dom1_2 << endl; + int ima = orderedOriginals.size(); + int mid = orderedOriginals.size() / 2; + //cerr << "ima=" << ima << " mid=" << mid << endl; + for (int i = 0; i < mid; i++) + orderedNodes.push_back(nodeDomains[orderedOriginals[i]][domain1]); + for (int i = 0; i < mid; i++) + orderedNodes.push_back(nodeDomains[orderedOriginals[i]][domain2]); + for (int i = mid; i < ima; i++) + orderedNodes.push_back(nodeDomains[orderedOriginals[i]][domain1]); + for (int i = mid; i < ima; i++) + orderedNodes.push_back(nodeDomains[orderedOriginals[i]][domain2]); + for (int i = 0; i < mid; i++) { - long dom1 = domain1; - long dom2 = domain2; - long dom1_2; // for nodeQuadDomains - if (domain1 < domain2) - dom1_2 = dom1 + INT_MAX * dom2; + int oldId = orderedOriginals[i]; + int newId; + if (nodeQuadDomains.count(oldId) && nodeQuadDomains[oldId].count(dom1_2)) + newId = nodeQuadDomains[oldId][dom1_2]; else - dom1_2 = dom2 + INT_MAX * dom1; - //cerr << "dom1=" << dom1 << " dom2=" << dom2 << " dom1_2=" << dom1_2 << endl; - int ima = orderedOriginals.size(); - int mid = orderedOriginals.size() / 2; - //cerr << "ima=" << ima << " mid=" << mid << endl; - for (int i = 0; i < mid; i++) - orderedNodes.push_back(nodeDomains[orderedOriginals[i]][domain1]); - for (int i = 0; i < mid; i++) - orderedNodes.push_back(nodeDomains[orderedOriginals[i]][domain2]); - for (int i = mid; i < ima; i++) - orderedNodes.push_back(nodeDomains[orderedOriginals[i]][domain1]); - for (int i = mid; i < ima; i++) - orderedNodes.push_back(nodeDomains[orderedOriginals[i]][domain2]); - for (int i = 0; i < mid; i++) + { + double *coords = this->GetPoint(oldId); + SMDS_MeshNode *newNode = _mesh->AddNode(coords[0], coords[1], coords[2]); + newId = newNode->GetVtkID(); + if (! nodeQuadDomains.count(oldId)) { - int oldId = orderedOriginals[i]; - int newId; - if (nodeQuadDomains.count(oldId) && nodeQuadDomains[oldId].count(dom1_2)) - newId = nodeQuadDomains[oldId][dom1_2]; - else - { - double *coords = this->GetPoint(oldId); - SMDS_MeshNode *newNode = _mesh->AddNode(coords[0], coords[1], coords[2]); - newId = newNode->GetVtkID(); - if (! nodeQuadDomains.count(oldId)) - { - std::map emptyMap; - nodeQuadDomains[oldId] = emptyMap; - } - nodeQuadDomains[oldId][dom1_2] = newId; - } - orderedNodes.push_back(newId); + std::map emptyMap; + nodeQuadDomains[oldId] = emptyMap; } + nodeQuadDomains[oldId][dom1_2] = newId; + } + orderedNodes.push_back(newId); } + } else - { + { + for (int i = 0; i < nbNodes; i++) + orderedNodes.push_back(nodeDomains[orderedOriginals[i]][domain1]); + if (dim == 3) for (int i = 0; i < nbNodes; i++) - orderedNodes.push_back(nodeDomains[orderedOriginals[i]][domain1]); - if (dim == 3) - for (int i = 0; i < nbNodes; i++) - orderedNodes.push_back(nodeDomains[orderedOriginals[i]][domain2]); - else - for (int i = nbNodes-1; i >= 0; i--) - orderedNodes.push_back(nodeDomains[orderedOriginals[i]][domain2]); + orderedNodes.push_back(nodeDomains[orderedOriginals[i]][domain2]); + else + for (int i = nbNodes-1; i >= 0; i--) + orderedNodes.push_back(nodeDomains[orderedOriginals[i]][domain2]); - } + } if (dim == 3) - { - SMDS_MeshVolume *vol = _mesh->AddVolumeFromVtkIds(orderedNodes); - return vol; - } + { + SMDS_MeshVolume *vol = _mesh->AddVolumeFromVtkIds(orderedNodes); + return vol; + } else if (dim == 2) + { + // bos #24368 + // orient face by the original one, as getOrderedNodesOfFace() not implemented for faces + const SMDS_MeshElement* origFace = _mesh->FindElementVtk( vtkVolId ); + int i0 = origFace->GetNodeIndex( _mesh->FindNodeVtk( orderedNodes[0] )); + int i1 = origFace->GetNodeIndex( _mesh->FindNodeVtk( orderedNodes[1] )); + int diff = i0 - i1; + // order of nodes must be reverse in face and origFace + bool oriOk = ( diff == 1 ) || ( diff == -3 ); + if ( !oriOk ) { - SMDS_MeshFace *face = _mesh->AddFaceFromVtkIds(orderedNodes); - return face; + SMDSAbs_EntityType type = isQuadratic ? SMDSEntity_Quad_Quadrangle : SMDSEntity_Quadrangle; + const std::vector& interlace = SMDS_MeshCell::reverseSmdsOrder( type ); + SMDS_MeshCell::applyInterlace( interlace, orderedNodes ); } + SMDS_MeshFace *face = _mesh->AddFaceFromVtkIds(orderedNodes); + return face; + } // TODO update sub-shape list of elements and nodes return 0; diff --git a/src/SMESH/MG_ADAPT.cxx b/src/SMESH/MG_ADAPT.cxx index 849a3f966..3530fe477 100644 --- a/src/SMESH/MG_ADAPT.cxx +++ b/src/SMESH/MG_ADAPT.cxx @@ -48,11 +48,12 @@ static std::string removeFile(std::string fileName, int& notOk) std::string errStr; notOk = std::remove(fileName.c_str()); if (notOk) errStr = ToComment("\n error while removing file : ") << fileName; - else errStr = ToComment("\n file : ") << fileName << " succesfully deleted! \n "; + else errStr = ToComment("\n file : ") << fileName << " succesfully deleted! \n "; return errStr; } -std::string MG_ADAPT::remove_extension(const std::string& filename) { +std::string MG_ADAPT::remove_extension(const std::string& filename) +{ size_t lastdot = filename.find_last_of("."); if (lastdot == std::string::npos) return filename; return filename.substr(0, lastdot); @@ -65,104 +66,103 @@ namespace return SMESH_File( fName ).exists(); } -// ======================================================================= -med_idt openMedFile(const std::string aFile) -// ======================================================================= -// renvoie le medId associe au fichier Med apres ouverture -{ - med_idt medIdt = MEDfileOpen(aFile.c_str(),MED_ACC_RDONLY); - if (medIdt <0) + // ======================================================================= + med_idt openMedFile(const std::string aFile) + // ======================================================================= + // renvoie le medId associe au fichier Med apres ouverture { - THROW_SALOME_EXCEPTION("\nThe med file " << aFile << " cannot be opened.\n"); - } - return medIdt; -} - - -// ======================================================================= -void getTimeStepInfos(std::string aFile, med_int& numdt, med_int& numit, std::string fieldName) -// ======================================================================= -{ -// Il faut voir si plusieurs maillages - - herr_t erreur = 0 ; - med_idt medIdt ; - - - // Ouverture du fichier - //~SCRUTE(aFile.toStdString()); - medIdt = openMedFile(aFile); - if ( medIdt < 0 ) return ; - // Lecture du nombre de champs - med_int ncha = MEDnField(medIdt) ; - if (ncha < 1 ) - { - //~addMessage( ToComment(" error: there is no field in ") << aFile, /*fatal=*/true ); - return; - } - // Lecture des caracteristiques du champs - - // Lecture du type du champ, des noms des composantes et du nom de l'unite - char nomcha [MED_NAME_SIZE+1]; - strcpy(nomcha, fieldName.c_str()); -// Lecture du nombre de composantes - med_int ncomp = MEDfieldnComponentByName(medIdt, nomcha); - char meshname[MED_NAME_SIZE+1]; - char * comp = (char*) malloc(ncomp*MED_SNAME_SIZE+1); - char * unit = (char*) malloc(ncomp*MED_SNAME_SIZE+1); - char dtunit[MED_SNAME_SIZE+1]; - med_bool local; - med_field_type typcha; - med_int nbofcstp; - erreur = MEDfieldInfoByName (medIdt, nomcha, meshname,&local,&typcha,comp,unit,dtunit, &nbofcstp); - free(comp); - free(unit); - if ( erreur < 0 ) - { - //~addMessage( ToComment(" error: error while reading field ") << nomcha << " in file " << aFile , /*fatal=*/true ); - return; - } - - med_float dt; - med_int tmp_numdt, tmp_numit; - - //~med_int step = data->myUseLastTimeStep ? nbofcstp : data->myTimeStep+1; - //~myPrint("step ", step); - erreur = MEDfieldComputingStepInfo ( medIdt, nomcha, 1, &numdt, &numit, &dt ); - for( int step = 1; step <= nbofcstp; step++ ) - { - erreur = MEDfieldComputingStepInfo ( medIdt, nomcha, step, &tmp_numdt, &tmp_numit, &dt ); - if(tmp_numdt > numdt) + med_idt medIdt = MEDfileOpen(aFile.c_str(),MED_ACC_RDONLY); + if (medIdt <0) { - numdt = tmp_numdt; - numit = tmp_numit; + THROW_SALOME_EXCEPTION("\nThe med file " << aFile << " cannot be opened.\n"); } + return medIdt; } - if ( erreur < 0 ) + + // ======================================================================= + void getTimeStepInfos(std::string aFile, med_int& numdt, med_int& numit, std::string fieldName) + // ======================================================================= { - //~addMessage( ToComment(" error: error while reading field ") << nomcha << "step (numdt, numit) = " <<"("<< numdt<< ", " - //numit<< ")" <<" in file " << aFile , /*fatal=*/true ); - return; + // Il faut voir si plusieurs maillages + + herr_t erreur = 0 ; + med_idt medIdt ; + + // Ouverture du fichier + //~SCRUTE(aFile.toStdString()); + medIdt = openMedFile(aFile); + if ( medIdt < 0 ) return ; + // Lecture du nombre de champs + med_int ncha = MEDnField(medIdt) ; + if (ncha < 1 ) + { + //~addMessage( ToComment(" error: there is no field in ") << aFile, /*fatal=*/true ); + return; + } + // Lecture des caracteristiques du champs + + // Lecture du type du champ, des noms des composantes et du nom de l'unite + char nomcha [MED_NAME_SIZE+1]; + strcpy(nomcha, fieldName.c_str()); + // Lecture du nombre de composantes + med_int ncomp = MEDfieldnComponentByName(medIdt, nomcha); + char meshname[MED_NAME_SIZE+1]; + char * comp = (char*) malloc(ncomp*MED_SNAME_SIZE+1); + char * unit = (char*) malloc(ncomp*MED_SNAME_SIZE+1); + char dtunit[MED_SNAME_SIZE+1]; + med_bool local; + med_field_type typcha; + med_int nbofcstp; + erreur = MEDfieldInfoByName (medIdt, nomcha, meshname,&local,&typcha,comp,unit,dtunit, &nbofcstp); + free(comp); + free(unit); + if ( erreur < 0 ) + { + //~addMessage( ToComment(" error: error while reading field ") << nomcha << " in file " << aFile , /*fatal=*/true ); + return; + } + + med_float dt; + med_int tmp_numdt, tmp_numit; + + //~med_int step = data->myUseLastTimeStep ? nbofcstp : data->myTimeStep+1; + //~myPrint("step ", step); + erreur = MEDfieldComputingStepInfo ( medIdt, nomcha, 1, &numdt, &numit, &dt ); + for( int step = 1; step <= nbofcstp; step++ ) + { + erreur = MEDfieldComputingStepInfo ( medIdt, nomcha, step, &tmp_numdt, &tmp_numit, &dt ); + if(tmp_numdt > numdt) + { + numdt = tmp_numdt; + numit = tmp_numit; + } + } + if ( erreur < 0 ) + { + //~addMessage( ToComment(" error: error while reading field ") << nomcha << "step (numdt, numit) = " <<"("<< numdt<< ", " + //numit<< ")" <<" in file " << aFile , /*fatal=*/true ); + return; + } + + // Fermeture du fichier + if ( medIdt > 0 ) MEDfileClose(medIdt); + } - // Fermeture du fichier - if ( medIdt > 0 ) MEDfileClose(medIdt); - -} - -struct GET_DEFAULT // struct used to get default value from GetOptionValue() -{ - bool isDefault; - operator bool* () { + struct GET_DEFAULT // struct used to get default value from GetOptionValue() + { + bool isDefault; + operator bool* () { return &isDefault; - } -}; + } + }; -class outFileStream : public std::ofstream{ -public: + class outFileStream : public std::ofstream{ + public: ~outFileStream(){close();} //to close file at dtor -}; -} + }; + +} // anonymous namespace //---------------------------------------------------------------------------------------- MgAdapt::MgAdapt() @@ -863,14 +863,15 @@ void MgAdapt::execCmd( const char* cmd, int& err) } std::ostream logStream(buf); - + #if defined(WIN32) -#if defined(UNICODE) +# if defined(UNICODE) const wchar_t * aCmd = Kernel_Utils::utf8_decode(cmd); + SMESHUtils::ArrayDeleter deleter( aCmd ); std::unique_ptr pipe(_wpopen(aCmd, O_RDONLY), _pclose ); -#else +# else std::unique_ptr pipe(_popen(cmd, "r"), _pclose ); -#endif +# endif #else std::unique_ptr pipe(popen(cmd, "r"), pclose ); #endif @@ -961,12 +962,12 @@ std::string MgAdapt::getCommandToRun() } //~else //~{ - //~// constant value TODO + //~// constant value TODO //~} // Check coherence between mesh dimension and option fo adaptation checkDimensionOptionAdaptation(); -// sizemap file is written only if level is higher than 3 + // sizemap file is written only if level is higher than 3 if ( verbosityLevel > 3) { std::string solFileOut = getFileName()+".sol"; @@ -1357,7 +1358,7 @@ void MgAdapt::convertMedFile(std::string& meshFormatMeshFileName, std::string& s MEDCoupling::MEDFileMeshes* meshes = mfd->getMeshes(); MEDCoupling::MEDFileMesh* fileMesh = meshes->getMeshAtPos(0); // ok only one mesh in file! if (meshNameOut =="") - meshNameOut = fileMesh->getName(); + meshNameOut = fileMesh->getName(); storeGroupsAndFams(fileMesh); MEDCoupling::MCAuto fields = MEDCoupling::MEDFileFields::New(); @@ -1533,18 +1534,18 @@ void MgAdapt::buildBackGroundMeshAndSolFiles(const std::vector& fie } MgAdapt::Status MgAdapt::addMessage(const std::string& msg, - const bool isFatal/*=false*/) + const bool isFatal/*=false*/) { if ( isFatal ) - _myErrorMessages.clear(); // warnings are useless if a fatal error encounters + _errorMessages.clear(); // warnings are useless if a fatal error encounters - _myErrorMessages.push_back( msg ); + _errorMessages.push_back( msg ); -//~MESSAGE(msg); + //~MESSAGE(msg); #ifdef _DEBUG_ std::cout << msg << std::endl; #endif - return ( _myStatus = isFatal ? MgAdapt::DRS_FAIL : MgAdapt::DRS_WARN_SKIP_ELEM ); + return ( _status = isFatal ? MgAdapt::DRS_FAIL : MgAdapt::DRS_WARN_SKIP_ELEM ); } void MgAdapt::updateTimeStepRank() diff --git a/src/SMESH/MG_ADAPT.hxx b/src/SMESH/MG_ADAPT.hxx index 4970ccce5..12629a9da 100644 --- a/src/SMESH/MG_ADAPT.hxx +++ b/src/SMESH/MG_ADAPT.hxx @@ -243,8 +243,8 @@ private : TOptionValues _defaultOptionValues; // default values TOptionNames _doubleOptions, _charOptions, _boolOptions; // to find a type of option - std::vector _myErrorMessages; - Status _myStatus; + std::vector _errorMessages; + Status _status; std::string meshFormatOutputMesh; std::vector< std::string> solFormatOutput; std::vector groupVec; diff --git a/src/SMESH/SMESH_Algo.cxx b/src/SMESH/SMESH_Algo.cxx index cb9cc7489..9575c5881 100644 --- a/src/SMESH/SMESH_Algo.cxx +++ b/src/SMESH/SMESH_Algo.cxx @@ -1068,6 +1068,7 @@ bool SMESH_2D_Algo::FixInternalNodes(const SMESH_ProxyMesh& mesh, return false; SMESH_MesherHelper helper( *mesh.GetMesh() ); + helper.SetSubShape( face ); // get all faces from a proxy sub-mesh typedef SMDS_StdIterator< const SMDS_MeshElement*, SMDS_ElemIteratorPtr > TIterator; @@ -1144,7 +1145,7 @@ bool SMESH_2D_Algo::FixInternalNodes(const SMESH_ProxyMesh& mesh, { ++iRow1, ++iRow2; - // get the first quad in the next face row + // get the first quad in the next face row if (( quad = SMESH_MeshAlgos::FindFaceInSet( nodeRows[iRow1][0], nodeRows[iRow1][1], allFaces, /*avoid=*/firstRowQuads, @@ -1184,17 +1185,28 @@ bool SMESH_2D_Algo::FixInternalNodes(const SMESH_ProxyMesh& mesh, // get params of the first (bottom) and last (top) node rows UVPtStructVec uvB( nodeRows[0].size() ), uvT( nodeRows[0].size() ); + bool uvOk = false, *toCheck = helper.GetPeriodicIndex() ? &uvOk : nullptr; + const bool isFix3D = helper.HasDegeneratedEdges(); for ( int isBot = 0; isBot < 2; ++isBot ) { + iRow1 = isBot ? 0 : nodeRows.size()-1; + iRow2 = isBot ? 1 : nodeRows.size()-2; UVPtStructVec & uvps = isBot ? uvB : uvT; - vector< const SMDS_MeshNode* >& nodes = nodeRows[ isBot ? 0 : nodeRows.size()-1 ]; - for ( size_t i = 0; i < nodes.size(); ++i ) + vector< const SMDS_MeshNode* >& nodes = nodeRows[ iRow1 ]; + const size_t rowLen = nodes.size(); + for ( size_t i = 0; i < rowLen; ++i ) { uvps[i].node = nodes[i]; - gp_XY uv = helper.GetNodeUV( face, uvps[i].node ); - uvps[i].u = uv.Coord(1); - uvps[i].v = uv.Coord(2); uvps[i].x = 0; + if ( !isFix3D ) + { + size_t i2 = i; + if ( i == 0 ) i2 = 1; + if ( i == rowLen - 1 ) i2 = rowLen - 2; + gp_XY uv = helper.GetNodeUV( face, uvps[i].node, nodeRows[iRow2][i2], toCheck ); + uvps[i].u = uv.Coord(1); + uvps[i].v = uv.Coord(2); + } } // calculate x (normalized param) for ( size_t i = 1; i < nodes.size(); ++i ) @@ -1207,15 +1219,23 @@ bool SMESH_2D_Algo::FixInternalNodes(const SMESH_ProxyMesh& mesh, UVPtStructVec uvL( nodeRows.size() ), uvR( nodeRows.size() ); for ( int isLeft = 0; isLeft < 2; ++isLeft ) { - UVPtStructVec & uvps = isLeft ? uvL : uvR; - const int iCol = isLeft ? 0 : nodeRows[0].size() - 1; - for ( size_t i = 0; i < nodeRows.size(); ++i ) + UVPtStructVec & uvps = isLeft ? uvL : uvR; + const int iCol1 = isLeft ? 0 : nodeRows[0].size() - 1; + const int iCol2 = isLeft ? 1 : nodeRows[0].size() - 2; + const size_t nbRows = nodeRows.size(); + for ( size_t i = 0; i < nbRows; ++i ) { - uvps[i].node = nodeRows[i][iCol]; - gp_XY uv = helper.GetNodeUV( face, uvps[i].node ); - uvps[i].u = uv.Coord(1); - uvps[i].v = uv.Coord(2); + uvps[i].node = nodeRows[i][iCol1]; uvps[i].y = 0; + if ( !isFix3D ) + { + size_t i2 = i; + if ( i == 0 ) i2 = 1; + if ( i == nbRows - 1 ) i2 = nbRows - 2; + gp_XY uv = helper.GetNodeUV( face, uvps[i].node, nodeRows[i2][iCol2], toCheck ); + uvps[i].u = uv.Coord(1); + uvps[i].v = uv.Coord(2); + } } // calculate y (normalized param) for ( size_t i = 1; i < nodeRows.size(); ++i ) @@ -1226,31 +1246,65 @@ bool SMESH_2D_Algo::FixInternalNodes(const SMESH_ProxyMesh& mesh, // update node coordinates SMESHDS_Mesh* meshDS = mesh.GetMeshDS(); - Handle(Geom_Surface) S = BRep_Tool::Surface( face ); - gp_XY a0 ( uvB.front().u, uvB.front().v ); - gp_XY a1 ( uvB.back().u, uvB.back().v ); - gp_XY a2 ( uvT.back().u, uvT.back().v ); - gp_XY a3 ( uvT.front().u, uvT.front().v ); - for ( size_t iRow = 1; iRow < nodeRows.size()-1; ++iRow ) + if ( !isFix3D ) { - gp_XY p1 ( uvR[ iRow ].u, uvR[ iRow ].v ); - gp_XY p3 ( uvL[ iRow ].u, uvL[ iRow ].v ); - const double y0 = uvL[ iRow ].y; - const double y1 = uvR[ iRow ].y; - for ( size_t iCol = 1; iCol < nodeRows[0].size()-1; ++iCol ) + Handle(Geom_Surface) S = BRep_Tool::Surface( face ); + gp_XY a0 ( uvB.front().u, uvB.front().v ); + gp_XY a1 ( uvB.back().u, uvB.back().v ); + gp_XY a2 ( uvT.back().u, uvT.back().v ); + gp_XY a3 ( uvT.front().u, uvT.front().v ); + for ( size_t iRow = 1; iRow < nodeRows.size()-1; ++iRow ) { - gp_XY p0 ( uvB[ iCol ].u, uvB[ iCol ].v ); - gp_XY p2 ( uvT[ iCol ].u, uvT[ iCol ].v ); - const double x0 = uvB[ iCol ].x; - const double x1 = uvT[ iCol ].x; - double x = (x0 + y0 * (x1 - x0)) / (1 - (y1 - y0) * (x1 - x0)); - double y = y0 + x * (y1 - y0); - gp_XY uv = helper.calcTFI( x, y, a0,a1,a2,a3, p0,p1,p2,p3 ); - gp_Pnt p = S->Value( uv.Coord(1), uv.Coord(2)); - const SMDS_MeshNode* n = nodeRows[iRow][iCol]; - meshDS->MoveNode( n, p.X(), p.Y(), p.Z() ); - if ( SMDS_FacePositionPtr pos = n->GetPosition() ) - pos->SetParameters( uv.Coord(1), uv.Coord(2) ); + gp_XY p1 ( uvR[ iRow ].u, uvR[ iRow ].v ); + gp_XY p3 ( uvL[ iRow ].u, uvL[ iRow ].v ); + const double y0 = uvL[ iRow ].y; + const double y1 = uvR[ iRow ].y; + for ( size_t iCol = 1; iCol < nodeRows[0].size()-1; ++iCol ) + { + gp_XY p0 ( uvB[ iCol ].u, uvB[ iCol ].v ); + gp_XY p2 ( uvT[ iCol ].u, uvT[ iCol ].v ); + const double x0 = uvB[ iCol ].x; + const double x1 = uvT[ iCol ].x; + double x = (x0 + y0 * (x1 - x0)) / (1 - (y1 - y0) * (x1 - x0)); + double y = y0 + x * (y1 - y0); + gp_XY uv = helper.calcTFI( x, y, a0,a1,a2,a3, p0,p1,p2,p3 ); + gp_Pnt p = S->Value( uv.Coord(1), uv.Coord(2)); + const SMDS_MeshNode* n = nodeRows[iRow][iCol]; + meshDS->MoveNode( n, p.X(), p.Y(), p.Z() ); + if ( SMDS_FacePositionPtr pos = n->GetPosition() ) + pos->SetParameters( uv.Coord(1), uv.Coord(2) ); + } + } + } + else + { + Handle(ShapeAnalysis_Surface) S = helper.GetSurface( face ); + SMESH_NodeXYZ a0 ( uvB.front().node ); + SMESH_NodeXYZ a1 ( uvB.back().node ); + SMESH_NodeXYZ a2 ( uvT.back().node ); + SMESH_NodeXYZ a3 ( uvT.front().node ); + for ( size_t iRow = 1; iRow < nodeRows.size()-1; ++iRow ) + { + SMESH_NodeXYZ p1 ( uvR[ iRow ].node ); + SMESH_NodeXYZ p3 ( uvL[ iRow ].node ); + const double y0 = uvL[ iRow ].y; + const double y1 = uvR[ iRow ].y; + for ( size_t iCol = 1; iCol < nodeRows[0].size()-1; ++iCol ) + { + SMESH_NodeXYZ p0 ( uvB[ iCol ].node ); + SMESH_NodeXYZ p2 ( uvT[ iCol ].node ); + const double x0 = uvB[ iCol ].x; + const double x1 = uvT[ iCol ].x; + double x = (x0 + y0 * (x1 - x0)) / (1 - (y1 - y0) * (x1 - x0)); + double y = y0 + x * (y1 - y0); + gp_Pnt p = helper.calcTFI( x, y, a0,a1,a2,a3, p0,p1,p2,p3 ); + gp_Pnt2d uv = S->ValueOfUV( p, Precision::Confusion() ); + p = S->Value( uv ); + const SMDS_MeshNode* n = nodeRows[iRow][iCol]; + meshDS->MoveNode( n, p.X(), p.Y(), p.Z() ); + if ( SMDS_FacePositionPtr pos = n->GetPosition() ) + pos->SetParameters( uv.Coord(1), uv.Coord(2) ); + } } } return true; diff --git a/src/SMESH/SMESH_Gen.cxx b/src/SMESH/SMESH_Gen.cxx index 399cef529..65e59d98d 100644 --- a/src/SMESH/SMESH_Gen.cxx +++ b/src/SMESH/SMESH_Gen.cxx @@ -1077,18 +1077,14 @@ std::vector< std::string > SMESH_Gen::GetPluginXMLPaths() xmlPath += sep + plugin + ".xml"; bool fileOK; #ifdef WIN32 - #ifdef UNICODE +# ifdef UNICODE const wchar_t* path = Kernel_Utils::decode_s(xmlPath); - #else + SMESHUtils::ArrayDeleter deleter( path ); +# else const char* path = xmlPath.c_str(); - #endif - +# endif fileOK = (GetFileAttributes(path) != INVALID_FILE_ATTRIBUTES); - #ifdef UNICODE - delete path; - #endif - #else fileOK = (access(xmlPath.c_str(), F_OK) == 0); #endif diff --git a/src/SMESH/SMESH_Hypothesis.cxx b/src/SMESH/SMESH_Hypothesis.cxx index 4f217d4b7..e0de00792 100644 --- a/src/SMESH/SMESH_Hypothesis.cxx +++ b/src/SMESH/SMESH_Hypothesis.cxx @@ -146,7 +146,7 @@ void SMESH_Hypothesis::SetLibName(const char* theLibName) //purpose : Find a mesh with given persistent ID //======================================================================= -SMESH_Mesh* SMESH_Hypothesis::GetMeshByPersistentID(int id) +SMESH_Mesh* SMESH_Hypothesis::GetMeshByPersistentID(int id) const { StudyContextStruct* myStudyContext = _gen->GetStudyContext(); map::iterator itm = myStudyContext->mapMesh.begin(); diff --git a/src/SMESH/SMESH_Hypothesis.hxx b/src/SMESH/SMESH_Hypothesis.hxx index 0558ac6f1..6ae7cdcc9 100644 --- a/src/SMESH/SMESH_Hypothesis.hxx +++ b/src/SMESH/SMESH_Hypothesis.hxx @@ -128,7 +128,7 @@ public: /*! * \brief Find a mesh with given persistent ID */ - SMESH_Mesh* GetMeshByPersistentID(int id); + SMESH_Mesh* GetMeshByPersistentID(int id) const; protected: SMESH_Gen* _gen; diff --git a/src/SMESH/SMESH_Mesh.cxx b/src/SMESH/SMESH_Mesh.cxx index 315bf6544..7c634c4de 100644 --- a/src/SMESH/SMESH_Mesh.cxx +++ b/src/SMESH/SMESH_Mesh.cxx @@ -103,7 +103,7 @@ class SMESH_Mesh::SubMeshHolder : public SMESHDS_TSubMeshHolder< SMESH_subMesh > */ //============================================================================= -SMESH_Mesh::SMESH_Mesh(int theLocalId, +SMESH_Mesh::SMESH_Mesh(int theLocalId, SMESH_Gen* theGen, bool theIsEmbeddedMode, SMESHDS_Document* theDocument): @@ -112,15 +112,33 @@ SMESH_Mesh::SMESH_Mesh(int theLocalId, if(MYDEBUG) MESSAGE("SMESH_Mesh::SMESH_Mesh(int localId)"); _id = theLocalId; _gen = theGen; - _myDocument = theDocument; - _myMeshDS = theDocument->NewMesh(theIsEmbeddedMode,theLocalId); + _document = theDocument; + _meshDS = theDocument->NewMesh(theIsEmbeddedMode,theLocalId); _isShapeToMesh = false; _isAutoColor = false; _isModified = false; _shapeDiagonal = 0.0; _callUp = NULL; - _myMeshDS->ShapeToMesh( PseudoShape() ); + _meshDS->ShapeToMesh( PseudoShape() ); _subMeshHolder = new SubMeshHolder; + + // assure unique persistent ID + if ( _document->NbMeshes() > 1 ) + { + std::set< int > ids; + for ( _document->InitMeshesIterator(); _document->MoreMesh(); ) + { + SMESHDS_Mesh * meshDS =_document->NextMesh(); + if ( meshDS != _meshDS ) + ids.insert( meshDS->GetPersistentId() ); + } + + if ( ids.count( _meshDS->GetPersistentId() )) + { + int uniqueID = *ids.rbegin() + 1; + _meshDS->SetPersistentId( uniqueID ); + } + } } //================================================================================ @@ -134,8 +152,8 @@ SMESH_Mesh::SMESH_Mesh(): _groupId( 0 ), _nbSubShapes( 0 ), _isShapeToMesh( false ), - _myDocument( 0 ), - _myMeshDS( 0 ), + _document( 0 ), + _meshDS( 0 ), _gen( 0 ), _isAutoColor( false ), _isModified( false ), @@ -176,9 +194,9 @@ SMESH_Mesh::~SMESH_Mesh() { if(MYDEBUG) MESSAGE("SMESH_Mesh::~SMESH_Mesh"); - if ( _myDocument ) // avoid destructing _myMeshDS from ~SMESH_Gen() - _myDocument->RemoveMesh( _id ); - _myDocument = 0; + if ( _document ) // avoid destructing _meshDS from ~SMESH_Gen() + _document->RemoveMesh( _id ); + _document = 0; // remove self from studyContext if ( _gen ) @@ -187,7 +205,7 @@ SMESH_Mesh::~SMESH_Mesh() studyContext->mapMesh.erase( _id ); } - _myMeshDS->ClearMesh(); + _meshDS->ClearMesh(); // issue 0020340: EDF 1022 SMESH : Crash with FindNodeClosestTo in a second new study // Notify event listeners at least that something happens @@ -208,13 +226,13 @@ SMESH_Mesh::~SMESH_Mesh() if ( _callUp) delete _callUp; _callUp = 0; - if ( _myMeshDS ) { - // delete _myMeshDS, in a thread in order not to block closing a study with large meshes + if ( _meshDS ) { + // delete _meshDS, in a thread in order not to block closing a study with large meshes #ifndef WIN32 - boost::thread aThread(boost::bind( & deleteMeshDS, _myMeshDS )); + boost::thread aThread(boost::bind( & deleteMeshDS, _meshDS )); #else pthread_t thread; - int result=pthread_create(&thread, NULL, deleteMeshDS, (void*)_myMeshDS); + int result=pthread_create(&thread, NULL, deleteMeshDS, (void*)_meshDS); #endif } } @@ -227,7 +245,7 @@ SMESH_Mesh::~SMESH_Mesh() bool SMESH_Mesh::MeshExists( int meshId ) const { - return _myDocument ? bool( _myDocument->GetMesh( meshId )) : false; + return _document ? bool( _document->GetMesh( meshId )) : false; } //================================================================================ @@ -262,11 +280,11 @@ void SMESH_Mesh::ShapeToMesh(const TopoDS_Shape & aShape) if ( !aShape.IsNull() && _isShapeToMesh ) { if ( aShape.ShapeType() != TopAbs_COMPOUND && // group contents is allowed to change - _myMeshDS->ShapeToMesh().ShapeType() != TopAbs_COMPOUND ) + _meshDS->ShapeToMesh().ShapeType() != TopAbs_COMPOUND ) throw SALOME_Exception(LOCALIZED ("a shape to mesh has already been defined")); } // clear current data - if ( !_myMeshDS->ShapeToMesh().IsNull() ) + if ( !_meshDS->ShapeToMesh().IsNull() ) { // removal of a shape to mesh, delete objects referring to sub-shapes: // - sub-meshes @@ -275,7 +293,7 @@ void SMESH_Mesh::ShapeToMesh(const TopoDS_Shape & aShape) std::map ::iterator i_gr = _mapGroup.begin(); while ( i_gr != _mapGroup.end() ) { if ( dynamic_cast( i_gr->second->GetGroupDS() )) { - _myMeshDS->RemoveGroup( i_gr->second->GetGroupDS() ); + _meshDS->RemoveGroup( i_gr->second->GetGroupDS() ); delete i_gr->second; _mapGroup.erase( i_gr++ ); } @@ -286,7 +304,7 @@ void SMESH_Mesh::ShapeToMesh(const TopoDS_Shape & aShape) // clear SMESHDS TopoDS_Shape aNullShape; - _myMeshDS->ShapeToMesh( aNullShape ); + _meshDS->ShapeToMesh( aNullShape ); _shapeDiagonal = 0.0; } @@ -294,9 +312,9 @@ void SMESH_Mesh::ShapeToMesh(const TopoDS_Shape & aShape) // set a new geometry if ( !aShape.IsNull() ) { - _myMeshDS->ShapeToMesh(aShape); + _meshDS->ShapeToMesh(aShape); _isShapeToMesh = true; - _nbSubShapes = _myMeshDS->MaxShapeIndex(); + _nbSubShapes = _meshDS->MaxShapeIndex(); // fill map of ancestors fillAncestorsMap(aShape); @@ -305,7 +323,7 @@ void SMESH_Mesh::ShapeToMesh(const TopoDS_Shape & aShape) { _isShapeToMesh = false; _shapeDiagonal = 0.0; - _myMeshDS->ShapeToMesh( PseudoShape() ); + _meshDS->ShapeToMesh( PseudoShape() ); } _isModified = false; } @@ -318,7 +336,7 @@ void SMESH_Mesh::ShapeToMesh(const TopoDS_Shape & aShape) TopoDS_Shape SMESH_Mesh::GetShapeToMesh() const { - return _myMeshDS->ShapeToMesh(); + return _meshDS->ShapeToMesh(); } //======================================================================= @@ -411,7 +429,7 @@ void SMESH_Mesh::Clear() if ( HasShapeToMesh() ) // remove all nodes and elements { // clear mesh data - _myMeshDS->ClearMesh(); + _meshDS->ClearMesh(); // update compute state of submeshes if ( SMESH_subMesh *sm = GetSubMeshContaining( GetShapeToMesh() ) ) @@ -474,7 +492,7 @@ int SMESH_Mesh::UNVToMesh(const char* theFileName) _isShapeToMesh = false; DriverUNV_R_SMDS_Mesh myReader; - myReader.SetMesh(_myMeshDS); + myReader.SetMesh(_meshDS); myReader.SetFile(theFileName); myReader.SetMeshId(-1); myReader.Perform(); @@ -486,7 +504,7 @@ int SMESH_Mesh::UNVToMesh(const char* theFileName) { SMDS_MeshGroup* aGroup = gr2names->first; const std::string& aName = gr2names->second; - SMESHDS_Group* aGroupDS = new SMESHDS_Group( anId++, _myMeshDS, aGroup->GetType() ); + SMESHDS_Group* aGroupDS = new SMESHDS_Group( anId++, _meshDS, aGroup->GetType() ); aGroupDS->SMDSGroup() = std::move( *aGroup ); aGroupDS->SetStoreName( aName.c_str() ); AddGroup( aGroupDS ); @@ -507,7 +525,7 @@ int SMESH_Mesh::MEDToMesh(const char* theFileName, const char* theMeshName) _isShapeToMesh = false; DriverMED_R_SMESHDS_Mesh myReader; - myReader.SetMesh(_myMeshDS); + myReader.SetMesh(_meshDS); myReader.SetMeshId(-1); myReader.SetFile(theFileName); myReader.SetMeshName(theMeshName); @@ -532,8 +550,8 @@ int SMESH_Mesh::MEDToMesh(const char* theFileName, const char* theMeshName) } } - _myMeshDS->Modified(); - _myMeshDS->CompactMesh(); + _meshDS->Modified(); + _meshDS->CompactMesh(); return (int) status; } @@ -550,7 +568,7 @@ std::string SMESH_Mesh::STLToMesh(const char* theFileName) _isShapeToMesh = false; DriverSTL_R_SMDS_Mesh myReader; - myReader.SetMesh(_myMeshDS); + myReader.SetMesh(_meshDS); myReader.SetFile(theFileName); myReader.SetMeshId(-1); myReader.Perform(); @@ -574,7 +592,7 @@ int SMESH_Mesh::CGNSToMesh(const char* theFileName, #ifdef WITH_CGNS DriverCGNS_Read myReader; - myReader.SetMesh(_myMeshDS); + myReader.SetMesh(_meshDS); myReader.SetFile(theFileName); myReader.SetMeshId(theMeshIndex); res = myReader.Perform(); @@ -597,7 +615,7 @@ SMESH_ComputeErrorPtr SMESH_Mesh::GMFToMesh(const char* theFileName, bool theMakeRequiredGroups) { DriverGMF_Read myReader; - myReader.SetMesh(_myMeshDS); + myReader.SetMesh(_meshDS); myReader.SetFile(theFileName); myReader.SetMakeRequiredGroups( theMakeRequiredGroups ); myReader.Perform(); @@ -620,7 +638,6 @@ SMESH_Mesh::AddHypothesis(const TopoDS_Shape & aSubShape, int anHypId, std::string* anError ) { - Unexpect aCatch(SalomeException); if(MYDEBUG) MESSAGE("SMESH_Mesh::AddHypothesis"); if ( anError ) @@ -715,7 +732,6 @@ SMESH_Hypothesis::Hypothesis_Status SMESH_Mesh::RemoveHypothesis(const TopoDS_Shape & aSubShape, int anHypId) { - Unexpect aCatch(SalomeException); if(MYDEBUG) MESSAGE("SMESH_Mesh::RemoveHypothesis"); StudyContextStruct *sc = _gen->GetStudyContext(); @@ -785,7 +801,7 @@ SMESH_Mesh::RemoveHypothesis(const TopoDS_Shape & aSubShape, const std::list& SMESH_Mesh::GetHypothesisList(const TopoDS_Shape & aSubShape) const { - return _myMeshDS->GetHypothesis(aSubShape); + return _meshDS->GetHypothesis(aSubShape); } //======================================================================= @@ -828,7 +844,7 @@ const SMESH_Hypothesis * SMESH_Mesh::GetHypothesis(const SMESH_subMesh * aSubM { const TopoDS_Shape & aSubShape = aSubMesh->GetSubShape(); - const std::list& hypList = _myMeshDS->GetHypothesis(aSubShape); + const std::list& hypList = _meshDS->GetHypothesis(aSubShape); std::list::const_iterator hyp = hypList.begin(); for ( ; hyp != hypList.end(); hyp++ ) { const SMESH_Hypothesis * h = cSMESH_Hyp( *hyp ); @@ -849,7 +865,7 @@ const SMESH_Hypothesis * SMESH_Mesh::GetHypothesis(const SMESH_subMesh * aSubM for ( ; smIt != ancestors.end(); smIt++ ) { const TopoDS_Shape& curSh = (*smIt)->GetSubShape(); - const std::list& hypList = _myMeshDS->GetHypothesis(curSh); + const std::list& hypList = _meshDS->GetHypothesis(curSh); std::list::const_iterator hyp = hypList.begin(); for ( ; hyp != hypList.end(); hyp++ ) { const SMESH_Hypothesis * h = cSMESH_Hyp( *hyp ); @@ -921,7 +937,7 @@ int SMESH_Mesh::GetHypotheses(const SMESH_subMesh * aSubMesh, // get hypos from aSubShape { const TopoDS_Shape & aSubShape = aSubMesh->GetSubShape(); - const std::list& hypList = _myMeshDS->GetHypothesis(aSubShape); + const std::list& hypList = _meshDS->GetHypothesis(aSubShape); for ( hyp = hypList.begin(); hyp != hypList.end(); hyp++ ) { const SMESH_Hypothesis* h = cSMESH_Hyp( *hyp ); @@ -950,7 +966,7 @@ int SMESH_Mesh::GetHypotheses(const SMESH_subMesh * aSubMesh, for ( ; smIt != ancestors.end(); smIt++ ) { const TopoDS_Shape& curSh = (*smIt)->GetSubShape(); - const std::list& hypList = _myMeshDS->GetHypothesis(curSh); + const std::list& hypList = _meshDS->GetHypothesis(curSh); for ( hyp = hypList.begin(); hyp != hypList.end(); hyp++ ) { const SMESH_Hypothesis* h = cSMESH_Hyp( *hyp ); @@ -994,8 +1010,7 @@ SMESH_Hypothesis * SMESH_Mesh::GetHypothesis(const int anHypId) const const std::list & SMESH_Mesh::GetLog() { - Unexpect aCatch(SalomeException); - return _myMeshDS->GetScript()->GetCommands(); + return _meshDS->GetScript()->GetCommands(); } //============================================================================= @@ -1005,8 +1020,7 @@ const std::list & SMESH_Mesh::GetLog() //============================================================================= void SMESH_Mesh::ClearLog() { - Unexpect aCatch(SalomeException); - _myMeshDS->GetScript()->Clear(); + _meshDS->GetScript()->Clear(); } //============================================================================= @@ -1017,7 +1031,7 @@ void SMESH_Mesh::ClearLog() SMESH_subMesh * SMESH_Mesh::GetSubMesh(const TopoDS_Shape & aSubShape) { - int index = _myMeshDS->ShapeToIndex(aSubShape); + int index = _meshDS->ShapeToIndex(aSubShape); if ( !index && aSubShape.IsNull() ) return 0; @@ -1027,10 +1041,10 @@ SMESH_subMesh * SMESH_Mesh::GetSubMesh(const TopoDS_Shape & aSubShape) TopoDS_Iterator it( aSubShape ); if ( it.More() ) { - index = _myMeshDS->AddCompoundSubmesh( aSubShape, it.Value().ShapeType() ); + index = _meshDS->AddCompoundSubmesh( aSubShape, it.Value().ShapeType() ); // fill map of Ancestors while ( _nbSubShapes < index ) - fillAncestorsMap( _myMeshDS->IndexToShape( ++_nbSubShapes )); + fillAncestorsMap( _meshDS->IndexToShape( ++_nbSubShapes )); } } // if ( !index ) @@ -1039,7 +1053,7 @@ SMESH_subMesh * SMESH_Mesh::GetSubMesh(const TopoDS_Shape & aSubShape) SMESH_subMesh* aSubMesh = _subMeshHolder->Get( index ); if ( !aSubMesh ) { - aSubMesh = new SMESH_subMesh(index, this, _myMeshDS, aSubShape); + aSubMesh = new SMESH_subMesh(index, this, _meshDS, aSubShape); _subMeshHolder->Add( index, aSubMesh ); // include non-computable sub-meshes in SMESH_subMesh::_ancestors of sub-submeshes @@ -1069,7 +1083,7 @@ SMESH_subMesh * SMESH_Mesh::GetSubMesh(const TopoDS_Shape & aSubShape) SMESH_subMesh *SMESH_Mesh::GetSubMeshContaining(const TopoDS_Shape & aSubShape) const { - int index = _myMeshDS->ShapeToIndex(aSubShape); + int index = _meshDS->ShapeToIndex(aSubShape); return GetSubMeshContaining( index ); } @@ -1178,16 +1192,15 @@ bool SMESH_Mesh::IsUsedHypothesis(SMESHDS_Hypothesis * anHyp, void SMESH_Mesh::NotifySubMeshesHypothesisModification(const SMESH_Hypothesis* hyp) { - Unexpect aCatch(SalomeException); if ( !GetMeshDS()->IsUsedHypothesis( hyp )) return; - smIdType nbEntities = ( _myMeshDS->NbNodes() + _myMeshDS->NbElements() ); + smIdType nbEntities = ( _meshDS->NbNodes() + _meshDS->NbElements() ); if ( hyp && _callUp && !_callUp->IsLoaded() ) // for not loaded mesh (#16648) { _callUp->HypothesisModified( hyp->GetID(), /*updateIcons=*/true ); - nbEntities = ( _myMeshDS->NbNodes() + _myMeshDS->NbElements() ); // after loading mesh + nbEntities = ( _meshDS->NbNodes() + _meshDS->NbElements() ); // after loading mesh } SMESH_Algo *algo; @@ -1257,7 +1270,7 @@ void SMESH_Mesh::NotifySubMeshesHypothesisModification(const SMESH_Hypothesis* h HasModificationsToDiscard(); // to reset _isModified flag if mesh becomes empty GetMeshDS()->Modified(); - smIdType newNbEntities = ( _myMeshDS->NbNodes() + _myMeshDS->NbElements() ); + smIdType newNbEntities = ( _meshDS->NbNodes() + _meshDS->NbElements() ); if ( hyp && _callUp ) _callUp->HypothesisModified( hyp->GetID(), newNbEntities != nbEntities ); } @@ -1269,13 +1282,11 @@ void SMESH_Mesh::NotifySubMeshesHypothesisModification(const SMESH_Hypothesis* h //============================================================================= void SMESH_Mesh::SetAutoColor(bool theAutoColor) { - Unexpect aCatch(SalomeException); _isAutoColor = theAutoColor; } bool SMESH_Mesh::GetAutoColor() { - Unexpect aCatch(SalomeException); return _isAutoColor; } @@ -1394,71 +1405,50 @@ bool SMESH_Mesh::HasDuplicatedGroupNamesMED() //================================================================================ /*! - * \brief Export the mesh to a med file - * \param [in] file - name of the MED file - * \param [in] theMeshName - name of this mesh - * \param [in] theAutoGroups - boolean parameter for creating/not creating - * the groups Group_On_All_Nodes, Group_On_All_Faces, ... ; - * the typical use is auto_groups=false. - * \param [in] theVersion - define the minor (xy, where version is x.y.z) of MED file format. - * If theVersion is equal to -1, the minor version is not changed (default). - * \param [in] meshPart - mesh data to export - * \param [in] theAutoDimension - if \c true, a space dimension of a MED mesh can be either - * - 1D if all mesh nodes lie on OX coordinate axis, or - * - 2D if all mesh nodes lie on XOY coordinate plane, or - * - 3D in the rest cases. - * If \a theAutoDimension is \c false, the space dimension is always 3. - * \param [in] theAddODOnVertices - to create 0D elements on all vertices - * \param [in] theAllElemsToGroup - to make every element to belong to any group (PAL23413) - * \param [in] ZTolerance - tolerance in Z direction. If Z coordinate of a node is close to zero - * within a given tolerance, the coordinate is set to zero. - * If \a ZTolerance is negative, the node coordinates are kept as is. - * \return int - mesh index in the file + * \brief Export the mesh to a writer */ //================================================================================ -void SMESH_Mesh::ExportMED(const char * file, - const char* theMeshName, - bool theAutoGroups, - int theVersion, - const SMESHDS_Mesh* meshPart, - bool theAutoDimension, - bool theAddODOnVertices, - double theZTolerance, - bool theAllElemsToGroup) +void SMESH_Mesh::exportMEDCommmon(DriverMED_W_SMESHDS_Mesh& theWriter, + const char* theMeshName, + bool theAutoGroups, + const SMESHDS_Mesh* theMeshPart, + bool theAutoDimension, + bool theAddODOnVertices, + double theZTolerance, + bool theSaveNumbers, + bool theAllElemsToGroup) { - MESSAGE("MED_VERSION:"<< theVersion); + Driver_Mesh::Status status = Driver_Mesh::DRS_OK; - Driver_Mesh::Status status; SMESH_TRY; - DriverMED_W_SMESHDS_Mesh myWriter; - myWriter.SetFile ( file , theVersion); - myWriter.SetMesh ( meshPart ? (SMESHDS_Mesh*) meshPart : _myMeshDS ); - myWriter.SetAutoDimension( theAutoDimension ); - myWriter.AddODOnVertices ( theAddODOnVertices ); - myWriter.SetZTolerance ( theZTolerance ); + theWriter.SetMesh ( theMeshPart ? (SMESHDS_Mesh*) theMeshPart : _meshDS ); + theWriter.SetAutoDimension( theAutoDimension ); + theWriter.AddODOnVertices ( theAddODOnVertices ); + theWriter.SetZTolerance ( theZTolerance ); + theWriter.SetSaveNumbers ( theSaveNumbers ); if ( !theMeshName ) - myWriter.SetMeshId ( _id ); + theWriter.SetMeshId ( _id ); else { - myWriter.SetMeshId ( -1 ); - myWriter.SetMeshName ( theMeshName ); + theWriter.SetMeshId ( -1 ); + theWriter.SetMeshName ( theMeshName ); } if ( theAutoGroups ) { - myWriter.AddGroupOfNodes(); - myWriter.AddGroupOfEdges(); - myWriter.AddGroupOfFaces(); - myWriter.AddGroupOfVolumes(); - myWriter.AddGroupOf0DElems(); - myWriter.AddGroupOfBalls(); + theWriter.AddGroupOfNodes(); + theWriter.AddGroupOfEdges(); + theWriter.AddGroupOfFaces(); + theWriter.AddGroupOfVolumes(); + theWriter.AddGroupOf0DElems(); + theWriter.AddGroupOfBalls(); } if ( theAllElemsToGroup ) - myWriter.AddAllToGroup(); + theWriter.AddAllToGroup(); // Pass groups to writer. Provide unique group names. //set aGroupNames; // Corrected for Mantis issue 0020028 - if ( !meshPart ) + if ( !theMeshPart ) { std::map< SMDSAbs_ElementType, std::set > aGroupNames; char aString [256]; @@ -1479,12 +1469,12 @@ void SMESH_Mesh::ExportMED(const char * file, aGroupName.resize(MAX_MED_GROUP_NAME_LENGTH); } aGroupDS->SetStoreName( aGroupName.c_str() ); - myWriter.AddGroup( aGroupDS ); + theWriter.AddGroup( aGroupDS ); } } } // Perform export - status = myWriter.Perform(); + status = theWriter.Perform(); SMESH_CATCH( SMESH::throwSalomeEx ); @@ -1492,17 +1482,83 @@ void SMESH_Mesh::ExportMED(const char * file, throw TooLargeForExport("MED"); } +//================================================================================ +/*! + * Same as SMESH_Mesh::ExportMED except for \a file and \a theVersion + */ +//================================================================================ + +MEDCoupling::MCAuto +SMESH_Mesh::ExportMEDCoupling(const char* theMeshName, + bool theAutoGroups, + const SMESHDS_Mesh* theMeshPart, + bool theAutoDimension, + bool theAddODOnVertices, + double theZTolerance, + bool theSaveNumbers) +{ + DriverMED_W_SMESHDS_Mesh_Mem writer; + this->exportMEDCommmon( writer, theMeshName, theAutoGroups, theMeshPart, theAutoDimension, + theAddODOnVertices, theZTolerance, theSaveNumbers, + /*AllElemsToGroup(for ExportSAUV())=*/false); + return writer.getData(); +} + +//================================================================================ +/*! + * \brief Export the mesh to a med file + * \param [in] theFile - name of the MED file + * \param [in] theMeshName - name of this mesh + * \param [in] theAutoGroups - boolean parameter for creating/not creating + * the groups Group_On_All_Nodes, Group_On_All_Faces, ... ; + * the typical use is auto_groups=false. + * \param [in] theVersion - define the minor (xy, where version is x.y.z) of MED file format. + * If theVersion is equal to -1, the minor version is not changed (default). + * \param [in] theMeshPart - mesh data to export + * \param [in] theAutoDimension - if \c true, a space dimension of a MED mesh can be either + * - 1D if all mesh nodes lie on OX coordinate axis, or + * - 2D if all mesh nodes lie on XOY coordinate plane, or + * - 3D in the rest cases. + * If \a theAutoDimension is \c false, the space dimension is always 3. + * \param [in] theAddODOnVertices - to create 0D elements on all vertices + * \param [in] theZTolerance - tolerance in Z direction. If Z coordinate of a node is close to zero + * within a given tolerance, the coordinate is set to zero. + * If \a ZTolerance is negative, the node coordinates are kept as is. + * \param [in] theSaveNumbers : enable saving numbers of nodes and cells. + * \param [in] theAllElemsToGroup - to make every element to belong to any group (PAL23413). + * It is used by ExportSAUV() only + * \return int - mesh index in the file + */ +//================================================================================ + +void SMESH_Mesh::ExportMED(const char * theFile, + const char* theMeshName, + bool theAutoGroups, + int theVersion, + const SMESHDS_Mesh* theMeshPart, + bool theAutoDimension, + bool theAddODOnVertices, + double theZTolerance, + bool theSaveNumbers, + bool theAllElemsToGroup) +{ + MESSAGE("MED_VERSION:"<< theVersion); + DriverMED_W_SMESHDS_Mesh writer; + writer.SetFile( theFile, theVersion ); + this->exportMEDCommmon( writer, theMeshName, theAutoGroups, theMeshPart, theAutoDimension, theAddODOnVertices, theZTolerance, theSaveNumbers, theAllElemsToGroup ); +} + //================================================================================ /*! * \brief Export the mesh to a SAUV file */ //================================================================================ -void SMESH_Mesh::ExportSAUV(const char *file, - const char* theMeshName, - bool theAutoGroups) +void SMESH_Mesh::ExportSAUV(const char *theFile, + const char* theMeshName, + bool theAutoGroups) { - std::string medfilename(file); + std::string medfilename( theFile ); medfilename += ".med"; std::string cmd; #ifdef WIN32 @@ -1515,9 +1571,10 @@ void SMESH_Mesh::ExportSAUV(const char *file, cmd += "\""; system(cmd.c_str()); try { - ExportMED(medfilename.c_str(), theMeshName, theAutoGroups, /*minor=*/-1, - /*meshPart=*/NULL, /*theAutoDimension=*/false, /*theAddODOnVertices=*/false, - /*zTol=*/-1, /*theAllElemsToGroup=*/true ); // theAllElemsToGroup is for PAL0023413 + ExportMED( medfilename.c_str(), theMeshName, theAutoGroups, /*minor=*/-1, + /*meshPart=*/NULL, /*theAutoDimension=*/false, /*theAddODOnVertices=*/false, + /*zTol=*/-1, /*theSaveNumbers=*/false, + /*theAllElemsToGroup=*/true ); // theAllElemsToGroup is for PAL0023413 } catch ( TooLargeForExport ) { @@ -1529,7 +1586,7 @@ void SMESH_Mesh::ExportSAUV(const char *file, cmd = "python3 "; #endif cmd += "-c \""; - cmd += "from medutilities import convert ; convert(r'" + medfilename + "', 'MED', 'GIBI', 1, r'" + file + "')"; + cmd += "from medutilities import convert ; convert(r'" + medfilename + "', 'MED', 'GIBI', 1, r'" + theFile + "')"; cmd += "\""; system(cmd.c_str()); #ifdef WIN32 @@ -1550,16 +1607,18 @@ void SMESH_Mesh::ExportSAUV(const char *file, //================================================================================ void SMESH_Mesh::ExportDAT(const char * file, - const SMESHDS_Mesh* meshPart) + const SMESHDS_Mesh* meshPart, + const bool renumber) { Driver_Mesh::Status status; SMESH_TRY; - DriverDAT_W_SMDS_Mesh myWriter; - myWriter.SetFile( file ); - myWriter.SetMesh( meshPart ? (SMESHDS_Mesh*) meshPart : _myMeshDS ); - myWriter.SetMeshId(_id); - status = myWriter.Perform(); + DriverDAT_W_SMDS_Mesh writer; + writer.SetFile( file ); + writer.SetMesh( meshPart ? (SMESHDS_Mesh*) meshPart : _meshDS ); + writer.SetMeshId(_id); + writer.SetRenumber( renumber ); + status = writer.Perform(); SMESH_CATCH( SMESH::throwSalomeEx ); @@ -1574,16 +1633,17 @@ void SMESH_Mesh::ExportDAT(const char * file, //================================================================================ void SMESH_Mesh::ExportUNV(const char * file, - const SMESHDS_Mesh* meshPart) + const SMESHDS_Mesh* meshPart, + const bool renumber) { Driver_Mesh::Status status; SMESH_TRY; - DriverUNV_W_SMDS_Mesh myWriter; - myWriter.SetFile( file ); - myWriter.SetMesh( meshPart ? (SMESHDS_Mesh*) meshPart : _myMeshDS ); - myWriter.SetMeshId(_id); - // myWriter.SetGroups(_mapGroup); + DriverUNV_W_SMDS_Mesh writer; + writer.SetFile( file ); + writer.SetMesh( meshPart ? (SMESHDS_Mesh*) meshPart : _meshDS ); + writer.SetMeshId(_id); + writer.SetRenumber( renumber ); // pass group names to SMESHDS if ( !meshPart ) @@ -1595,11 +1655,11 @@ void SMESH_Mesh::ExportUNV(const char * file, if ( aGroupDS ) { std::string aGroupName = aGroup->GetName(); aGroupDS->SetStoreName( aGroupName.c_str() ); - myWriter.AddGroup( aGroupDS ); + writer.AddGroup( aGroupDS ); } } } - status = myWriter.Perform(); + status = writer.Perform(); SMESH_CATCH( SMESH::throwSalomeEx ); @@ -1621,13 +1681,13 @@ void SMESH_Mesh::ExportSTL(const char * file, Driver_Mesh::Status status; SMESH_TRY; - DriverSTL_W_SMDS_Mesh myWriter; - myWriter.SetFile( file ); - myWriter.SetIsAscii( isascii ); - myWriter.SetMesh( meshPart ? (SMESHDS_Mesh*) meshPart : _myMeshDS); - myWriter.SetMeshId(_id); - if ( name ) myWriter.SetName( name ); - status = myWriter.Perform(); + DriverSTL_W_SMDS_Mesh writer; + writer.SetFile( file ); + writer.SetIsAscii( isascii ); + writer.SetMesh( meshPart ? (SMESHDS_Mesh*) meshPart : _meshDS); + writer.SetMeshId(_id); + if ( name ) writer.SetName( name ); + status = writer.Perform(); SMESH_CATCH( SMESH::throwSalomeEx ); @@ -1662,17 +1722,17 @@ void SMESH_Mesh::ExportCGNS(const char * file, } #ifdef WITH_CGNS - DriverCGNS_Write myWriter; - myWriter.SetFile( file ); - myWriter.SetMesh( const_cast( meshDS )); - myWriter.SetMeshName( SMESH_Comment("Mesh_") << meshDS->GetPersistentId()); + DriverCGNS_Write writer; + writer.SetFile( file ); + writer.SetMesh( const_cast( meshDS )); + writer.SetMeshName( SMESH_Comment("Mesh_") << meshDS->GetPersistentId()); if ( meshName && meshName[0] ) - myWriter.SetMeshName( meshName ); - myWriter.SetElementsByType( groupElemsByType ); - res = myWriter.Perform(); + writer.SetMeshName( meshName ); + writer.SetElementsByType( groupElemsByType ); + res = writer.Perform(); if ( res != Driver_Mesh::DRS_OK ) { - SMESH_ComputeErrorPtr err = myWriter.GetError(); + SMESH_ComputeErrorPtr err = writer.GetError(); if ( err && !err->IsOK() && !err->myComment.empty() ) throw SALOME_Exception(("Export failed: " + err->myComment ).c_str() ); } @@ -1700,12 +1760,12 @@ void SMESH_Mesh::ExportGMF(const char * file, Driver_Mesh::Status status; SMESH_TRY; - DriverGMF_Write myWriter; - myWriter.SetFile( file ); - myWriter.SetMesh( const_cast( meshDS )); - myWriter.SetExportRequiredGroups( withRequiredGroups ); + DriverGMF_Write writer; + writer.SetFile( file ); + writer.SetMesh( const_cast( meshDS )); + writer.SetExportRequiredGroups( withRequiredGroups ); - status = myWriter.Perform(); + status = writer.Perform(); SMESH_CATCH( SMESH::throwSalomeEx ); @@ -1795,8 +1855,7 @@ double SMESH_Mesh::GetComputeProgress() const smIdType SMESH_Mesh::NbNodes() const { - Unexpect aCatch(SalomeException); - return _myMeshDS->NbNodes(); + return _meshDS->NbNodes(); } //================================================================================ @@ -1807,8 +1866,7 @@ smIdType SMESH_Mesh::NbNodes() const smIdType SMESH_Mesh::Nb0DElements() const { - Unexpect aCatch(SalomeException); - return _myMeshDS->GetMeshInfo().Nb0DElements(); + return _meshDS->GetMeshInfo().Nb0DElements(); } //================================================================================ @@ -1819,8 +1877,7 @@ smIdType SMESH_Mesh::Nb0DElements() const smIdType SMESH_Mesh::NbEdges(SMDSAbs_ElementOrder order) const { - Unexpect aCatch(SalomeException); - return _myMeshDS->GetMeshInfo().NbEdges(order); + return _meshDS->GetMeshInfo().NbEdges(order); } //================================================================================ @@ -1831,8 +1888,7 @@ smIdType SMESH_Mesh::NbEdges(SMDSAbs_ElementOrder order) const smIdType SMESH_Mesh::NbFaces(SMDSAbs_ElementOrder order) const { - Unexpect aCatch(SalomeException); - return _myMeshDS->GetMeshInfo().NbFaces(order); + return _meshDS->GetMeshInfo().NbFaces(order); } //================================================================================ @@ -1843,8 +1899,7 @@ smIdType SMESH_Mesh::NbFaces(SMDSAbs_ElementOrder order) const smIdType SMESH_Mesh::NbTriangles(SMDSAbs_ElementOrder order) const { - Unexpect aCatch(SalomeException); - return _myMeshDS->GetMeshInfo().NbTriangles(order); + return _meshDS->GetMeshInfo().NbTriangles(order); } //================================================================================ @@ -1855,8 +1910,7 @@ smIdType SMESH_Mesh::NbTriangles(SMDSAbs_ElementOrder order) const smIdType SMESH_Mesh::NbBiQuadTriangles() const { - Unexpect aCatch(SalomeException); - return _myMeshDS->GetMeshInfo().NbBiQuadTriangles(); + return _meshDS->GetMeshInfo().NbBiQuadTriangles(); } //================================================================================ @@ -1867,8 +1921,7 @@ smIdType SMESH_Mesh::NbBiQuadTriangles() const smIdType SMESH_Mesh::NbQuadrangles(SMDSAbs_ElementOrder order) const { - Unexpect aCatch(SalomeException); - return _myMeshDS->GetMeshInfo().NbQuadrangles(order); + return _meshDS->GetMeshInfo().NbQuadrangles(order); } //================================================================================ @@ -1879,8 +1932,7 @@ smIdType SMESH_Mesh::NbQuadrangles(SMDSAbs_ElementOrder order) const smIdType SMESH_Mesh::NbBiQuadQuadrangles() const { - Unexpect aCatch(SalomeException); - return _myMeshDS->GetMeshInfo().NbBiQuadQuadrangles(); + return _meshDS->GetMeshInfo().NbBiQuadQuadrangles(); } //================================================================================ @@ -1891,8 +1943,7 @@ smIdType SMESH_Mesh::NbBiQuadQuadrangles() const smIdType SMESH_Mesh::NbPolygons(SMDSAbs_ElementOrder order) const { - Unexpect aCatch(SalomeException); - return _myMeshDS->GetMeshInfo().NbPolygons(order); + return _meshDS->GetMeshInfo().NbPolygons(order); } //================================================================================ @@ -1903,8 +1954,7 @@ smIdType SMESH_Mesh::NbPolygons(SMDSAbs_ElementOrder order) const smIdType SMESH_Mesh::NbVolumes(SMDSAbs_ElementOrder order) const { - Unexpect aCatch(SalomeException); - return _myMeshDS->GetMeshInfo().NbVolumes(order); + return _meshDS->GetMeshInfo().NbVolumes(order); } //================================================================================ @@ -1915,8 +1965,7 @@ smIdType SMESH_Mesh::NbVolumes(SMDSAbs_ElementOrder order) const smIdType SMESH_Mesh::NbTetras(SMDSAbs_ElementOrder order) const { - Unexpect aCatch(SalomeException); - return _myMeshDS->GetMeshInfo().NbTetras(order); + return _meshDS->GetMeshInfo().NbTetras(order); } //================================================================================ @@ -1927,8 +1976,7 @@ smIdType SMESH_Mesh::NbTetras(SMDSAbs_ElementOrder order) const smIdType SMESH_Mesh::NbHexas(SMDSAbs_ElementOrder order) const { - Unexpect aCatch(SalomeException); - return _myMeshDS->GetMeshInfo().NbHexas(order); + return _meshDS->GetMeshInfo().NbHexas(order); } //================================================================================ @@ -1939,8 +1987,7 @@ smIdType SMESH_Mesh::NbHexas(SMDSAbs_ElementOrder order) const smIdType SMESH_Mesh::NbTriQuadraticHexas() const { - Unexpect aCatch(SalomeException); - return _myMeshDS->GetMeshInfo().NbTriQuadHexas(); + return _meshDS->GetMeshInfo().NbTriQuadHexas(); } //================================================================================ @@ -1951,8 +1998,7 @@ smIdType SMESH_Mesh::NbTriQuadraticHexas() const smIdType SMESH_Mesh::NbPyramids(SMDSAbs_ElementOrder order) const { - Unexpect aCatch(SalomeException); - return _myMeshDS->GetMeshInfo().NbPyramids(order); + return _meshDS->GetMeshInfo().NbPyramids(order); } //================================================================================ @@ -1963,20 +2009,17 @@ smIdType SMESH_Mesh::NbPyramids(SMDSAbs_ElementOrder order) const smIdType SMESH_Mesh::NbPrisms(SMDSAbs_ElementOrder order) const { - Unexpect aCatch(SalomeException); - return _myMeshDS->GetMeshInfo().NbPrisms(order); + return _meshDS->GetMeshInfo().NbPrisms(order); } smIdType SMESH_Mesh::NbQuadPrisms() const { - Unexpect aCatch(SalomeException); - return _myMeshDS->GetMeshInfo().NbQuadPrisms(); + return _meshDS->GetMeshInfo().NbQuadPrisms(); } smIdType SMESH_Mesh::NbBiQuadPrisms() const { - Unexpect aCatch(SalomeException); - return _myMeshDS->GetMeshInfo().NbBiQuadPrisms(); + return _meshDS->GetMeshInfo().NbBiQuadPrisms(); } @@ -1988,8 +2031,7 @@ smIdType SMESH_Mesh::NbBiQuadPrisms() const smIdType SMESH_Mesh::NbHexagonalPrisms() const { - Unexpect aCatch(SalomeException); - return _myMeshDS->GetMeshInfo().NbHexPrisms(); + return _meshDS->GetMeshInfo().NbHexPrisms(); } //================================================================================ @@ -2000,8 +2042,7 @@ smIdType SMESH_Mesh::NbHexagonalPrisms() const smIdType SMESH_Mesh::NbPolyhedrons() const { - Unexpect aCatch(SalomeException); - return _myMeshDS->GetMeshInfo().NbPolyhedrons(); + return _meshDS->GetMeshInfo().NbPolyhedrons(); } //================================================================================ @@ -2012,8 +2053,7 @@ smIdType SMESH_Mesh::NbPolyhedrons() const smIdType SMESH_Mesh::NbBalls() const { - Unexpect aCatch(SalomeException); - return _myMeshDS->GetMeshInfo().NbBalls(); + return _meshDS->GetMeshInfo().NbBalls(); } //================================================================================ @@ -2024,8 +2064,7 @@ smIdType SMESH_Mesh::NbBalls() const smIdType SMESH_Mesh::NbSubMesh() const { - Unexpect aCatch(SalomeException); - return _myMeshDS->NbSubMesh(); + return _meshDS->NbSubMesh(); } //================================================================================ @@ -2037,7 +2076,7 @@ smIdType SMESH_Mesh::NbSubMesh() const int SMESH_Mesh::NbMeshes() const // nb meshes in the Study { - return _myDocument->NbMeshes(); + return _document->NbMeshes(); } //======================================================================= @@ -2050,7 +2089,7 @@ bool SMESH_Mesh::IsNotConformAllowed() const if(MYDEBUG) MESSAGE("SMESH_Mesh::IsNotConformAllowed"); static SMESH_HypoFilter filter( SMESH_HypoFilter::HasName( "NotConformAllowed" )); - return GetHypothesis( _myMeshDS->ShapeToMesh(), filter, false ); + return GetHypothesis( _meshDS->ShapeToMesh(), filter, false ); } //======================================================================= @@ -2060,7 +2099,7 @@ bool SMESH_Mesh::IsNotConformAllowed() const bool SMESH_Mesh::IsMainShape(const TopoDS_Shape& theShape) const { - return theShape.IsSame(_myMeshDS->ShapeToMesh() ); + return theShape.IsSame(_meshDS->ShapeToMesh() ); } //======================================================================= @@ -2135,7 +2174,7 @@ SMESH_Group* SMESH_Mesh::AddGroup (SMESHDS_GroupBase* groupDS) bool SMESH_Mesh::SynchronizeGroups() { const size_t nbGroups = _mapGroup.size(); - const std::set& groups = _myMeshDS->GetGroups(); + const std::set& groups = _meshDS->GetGroups(); std::set::const_iterator gIt = groups.begin(); for ( ; gIt != groups.end(); ++gIt ) { @@ -2268,7 +2307,7 @@ ostream& SMESH_Mesh::Dump(ostream& save) save << clause << ".2) Number of " << orderStr << " quadrangles:\t" << nb4 << endl; if ( nb3 + nb4 != NbFaces(order) ) { std::map myFaceMap; - SMDS_FaceIteratorPtr itFaces=_myMeshDS->facesIterator(); + SMDS_FaceIteratorPtr itFaces=_meshDS->facesIterator(); while( itFaces->more( ) ) { int nbNodes = itFaces->next()->NbNodes(); if ( myFaceMap.find( nbNodes ) == myFaceMap.end() ) @@ -2293,7 +2332,7 @@ ostream& SMESH_Mesh::Dump(ostream& save) save << clause << ".4) Number of " << orderStr << " pyramids: \t" << nb5 << endl; if ( nb8 + nb4 + nb5 + nb6 != NbVolumes(order) ) { std::map myVolumesMap; - SMDS_VolumeIteratorPtr itVolumes=_myMeshDS->volumesIterator(); + SMDS_VolumeIteratorPtr itVolumes=_meshDS->volumesIterator(); while( itVolumes->more( ) ) { int nbNodes = itVolumes->next()->NbNodes(); if ( myVolumesMap.find( nbNodes ) == myVolumesMap.end() ) @@ -2319,7 +2358,7 @@ ostream& SMESH_Mesh::Dump(ostream& save) SMDSAbs_ElementType SMESH_Mesh::GetElementType( const smIdType id, const bool iselem ) { - return _myMeshDS->GetElementType( id, iselem ); + return _meshDS->GetElementType( id, iselem ); } //============================================================================= @@ -2370,7 +2409,7 @@ SMESH_Group* SMESH_Mesh::ConvertToStandalone ( int theGroupID ) void SMESH_Mesh::ClearMeshOrder() { - _mySubMeshOrder.clear(); + _subMeshOrder.clear(); } //============================================================================= @@ -2381,7 +2420,7 @@ void SMESH_Mesh::ClearMeshOrder() void SMESH_Mesh::SetMeshOrder(const TListOfListOfInt& theOrder ) { - _mySubMeshOrder = theOrder; + _subMeshOrder = theOrder; } //============================================================================= @@ -2392,7 +2431,7 @@ void SMESH_Mesh::SetMeshOrder(const TListOfListOfInt& theOrder ) const TListOfListOfInt& SMESH_Mesh::GetMeshOrder() const { - return _mySubMeshOrder; + return _subMeshOrder; } //============================================================================= @@ -2453,7 +2492,7 @@ void SMESH_Mesh::fillAncestorsMap(const TopoDS_Shape& theShape) bool SMESH_Mesh::SortByMeshOrder(std::vector& theListToSort) const { - if ( _mySubMeshOrder.empty() || theListToSort.size() < 2 ) + if ( _subMeshOrder.empty() || theListToSort.size() < 2 ) return true; @@ -2464,9 +2503,9 @@ bool SMESH_Mesh::SortByMeshOrder(std::vector& theListToSort) con typedef std::vector::iterator TPosInList; std::map< size_t, size_t > sortedPos; // index in theListToSort to order TPosInList smBeg = theListToSort.begin(), smEnd = theListToSort.end(); - TListOfListOfInt::const_iterator listIdsIt = _mySubMeshOrder.begin(); + TListOfListOfInt::const_iterator listIdsIt = _subMeshOrder.begin(); bool needSort = false; - for( ; listIdsIt != _mySubMeshOrder.end(); listIdsIt++) + for( ; listIdsIt != _subMeshOrder.end(); listIdsIt++) { const TListOfInt& listOfId = *listIdsIt; // convert sm ids to sm's @@ -2544,8 +2583,8 @@ bool SMESH_Mesh::SortByMeshOrder(std::vector& theListToSort) con bool SMESH_Mesh::IsOrderOK( const SMESH_subMesh* smBefore, const SMESH_subMesh* smAfter ) const { - TListOfListOfInt::const_iterator listIdsIt = _mySubMeshOrder.begin(); - for( ; listIdsIt != _mySubMeshOrder.end(); listIdsIt++) + TListOfListOfInt::const_iterator listIdsIt = _subMeshOrder.begin(); + for( ; listIdsIt != _subMeshOrder.end(); listIdsIt++) { const TListOfInt& listOfId = *listIdsIt; int iB = -1, iA = -1, i = 0; diff --git a/src/SMESH/SMESH_Mesh.hxx b/src/SMESH/SMESH_Mesh.hxx index ea3e18dc6..81495db9c 100644 --- a/src/SMESH/SMESH_Mesh.hxx +++ b/src/SMESH/SMESH_Mesh.hxx @@ -41,6 +41,8 @@ #include #include +#include "MEDCouplingMemArray.hxx" + #include #include #include @@ -62,6 +64,8 @@ class SMESH_HypoFilter; class SMESH_subMesh; class TopoDS_Solid; +class DriverMED_W_SMESHDS_Mesh; + typedef std::list TListOfInt; typedef std::list TListOfListOfInt; @@ -174,9 +178,9 @@ class SMESH_EXPORT SMESH_Mesh SMESH_Mesh* FindMesh( int meshId ) const; - SMESHDS_Mesh * GetMeshDS() { return _myMeshDS; } + SMESHDS_Mesh * GetMeshDS() { return _meshDS; } - const SMESHDS_Mesh * GetMeshDS() const { return _myMeshDS; } + const SMESHDS_Mesh * GetMeshDS() const { return _meshDS; } SMESH_Gen *GetGen() { return _gen; } @@ -261,6 +265,15 @@ class SMESH_EXPORT SMESH_Mesh TooLargeForExport(const char* format):runtime_error(format) {} }; + MEDCoupling::MCAuto + ExportMEDCoupling(const char* theMeshName = NULL, + bool theAutoGroups = true, + const SMESHDS_Mesh* theMeshPart = 0, + bool theAutoDimension = false, + bool theAddODOnVertices = false, + double theZTolerance = -1., + bool theSaveNumbers = true); + void ExportMED(const char * theFile, const char* theMeshName = NULL, bool theAutoGroups = true, @@ -269,12 +282,15 @@ class SMESH_EXPORT SMESH_Mesh bool theAutoDimension = false, bool theAddODOnVertices = false, double theZTolerance = -1., + bool theSaveNumbers = true, bool theAllElemsToGroup = false); void ExportDAT(const char * file, - const SMESHDS_Mesh* meshPart = 0); + const SMESHDS_Mesh* meshPart = 0, + const bool renumber = true); void ExportUNV(const char * file, - const SMESHDS_Mesh* meshPart = 0); + const SMESHDS_Mesh* meshPart = 0, + const bool renumber = true); void ExportSTL(const char * file, const bool isascii, const char * name = 0, @@ -372,6 +388,17 @@ class SMESH_EXPORT SMESH_Mesh private: + void exportMEDCommmon(DriverMED_W_SMESHDS_Mesh& myWriter, + const char* theMeshName, + bool theAutoGroups, + const SMESHDS_Mesh* meshPart, + bool theAutoDimension, + bool theAddODOnVertices, + double theZTolerance, + bool theSaveNumbers, + bool theAllElemsToGroup); + + private: void fillAncestorsMap(const TopoDS_Shape& theShape); void getAncestorsSubMeshes(const TopoDS_Shape& theSubShape, std::vector< SMESH_subMesh* >& theSubMeshes) const; @@ -381,8 +408,8 @@ protected: int _groupId; // id generator for group objects int _nbSubShapes; // initial nb of subshapes in the shape to mesh bool _isShapeToMesh;// set to true when a shape is given (only once) - SMESHDS_Document * _myDocument; - SMESHDS_Mesh * _myMeshDS; + SMESHDS_Document * _document; + SMESHDS_Mesh * _meshDS; SMESH_Gen * _gen; std::map _mapGroup; @@ -398,7 +425,7 @@ protected: mutable std::vector _ancestorSubMeshes; // to speed up GetHypothes[ei]s() - TListOfListOfInt _mySubMeshOrder; + TListOfListOfInt _subMeshOrder; // Struct calling methods at CORBA API implementation level, used to // 1) make an upper level (SMESH_I) be consistent with a lower one (SMESH) diff --git a/src/SMESH/SMESH_MeshEditor.cxx b/src/SMESH/SMESH_MeshEditor.cxx index 22695bac0..ff121002f 100644 --- a/src/SMESH/SMESH_MeshEditor.cxx +++ b/src/SMESH/SMESH_MeshEditor.cxx @@ -6959,9 +6959,19 @@ void SMESH_MeshEditor::MergeNodes (TListOfListOfNodes & theGroupsOfNodes, for ( size_t i = 0; i < newElemDefs.size(); ++i ) { - if ( i > 0 || !mesh->ChangeElementNodes( elem, - & newElemDefs[i].myNodes[0], - newElemDefs[i].myNodes.size() )) + bool elemChanged = false; + if ( i == 0 ) + { + if ( elem->GetGeomType() == SMDSGeom_POLYHEDRA ) + elemChanged = mesh->ChangePolyhedronNodes( elem, + newElemDefs[i].myNodes, + newElemDefs[i].myPolyhedQuantities ); + else + elemChanged = mesh->ChangeElementNodes( elem, + & newElemDefs[i].myNodes[0], + newElemDefs[i].myNodes.size() ); + } + if ( i > 0 || !elemChanged ) { if ( i == 0 ) { @@ -7128,6 +7138,7 @@ bool SMESH_MeshEditor::applyMerge( const SMDS_MeshElement* elem, // each face has to be analyzed in order to check volume validity if ( const SMDS_MeshVolume* aPolyedre = SMDS_Mesh::DownCast< SMDS_MeshVolume >( elem )) { + toRemove = false; int nbFaces = aPolyedre->NbFaces(); vector& poly_nodes = newElemDefs[0].myNodes; @@ -11107,16 +11118,9 @@ bool SMESH_MeshEditor::DoubleNodesOnGroupBoundaries( const std::vector, DownIdCompare> faceDomains; // face --> (id domain --> id volume) - std::mapcelldom; // cell vtkId --> domain + std::map celldom; // cell vtkId --> domain std::map, DownIdCompare> cellDomains; // oldNode --> (id domain --> id cell) std::map > nodeDomains; // oldId --> (domainId --> newId) - faceDomains.clear(); - celldom.clear(); - cellDomains.clear(); - nodeDomains.clear(); - std::map emptyMap; - std::set emptySet; - emptyMap.clear(); //MESSAGE(".. Number of domains :"<first; //MESSAGE(" --- face " << face.cellId); std::set oldNodes; - oldNodes.clear(); grid->GetNodeIds(oldNodes, face.cellId, face.cellType); std::set::iterator itn = oldNodes.begin(); for (; itn != oldNodes.end(); ++itn) @@ -11281,7 +11284,6 @@ bool SMESH_MeshEditor::DoubleNodesOnGroupBoundaries( const std::vectorfirst; //MESSAGE(" --- face " << face.cellId); std::set oldNodes; - oldNodes.clear(); grid->GetNodeIds(oldNodes, face.cellId, face.cellType); std::set::iterator itn = oldNodes.begin(); for (; itn != oldNodes.end(); ++itn) @@ -11342,7 +11344,6 @@ bool SMESH_MeshEditor::DoubleNodesOnGroupBoundaries( const std::vectorfirst; //MESSAGE(" --- face " << face.cellId); std::set oldNodes; - oldNodes.clear(); grid->GetNodeIds(oldNodes, face.cellId, face.cellType); int nbMultipleNodes = 0; std::set::iterator itn = oldNodes.begin(); @@ -11467,7 +11468,7 @@ bool SMESH_MeshEditor::DoubleNodesOnGroupBoundaries( const std::vector mapOfJunctionGroups; //MESSAGE(".. Creation of elements: simple junction"); - if (createJointElems) + if ( createJointElems ) { string joints2DName = "joints2D"; mapOfJunctionGroups[joints2DName] = this->myMesh->AddGroup(SMDSAbs_Face, joints2DName.c_str()); @@ -11482,15 +11483,14 @@ bool SMESH_MeshEditor::DoubleNodesOnGroupBoundaries( const std::vectorfirst; std::set oldNodes; std::set::iterator itn; - oldNodes.clear(); grid->GetNodeIds(oldNodes, face.cellId, face.cellType); - std::map domvol = itface->second; + std::map domvol = itface->second; std::map::iterator itdom = domvol.begin(); - int dom1 = itdom->first; + int dom1 = itdom->first; int vtkVolId = itdom->second; itdom++; - int dom2 = itdom->first; + int dom2 = itdom->first; SMDS_MeshCell *vol = grid->extrudeVolumeFromFace(vtkVolId, dom1, dom2, oldNodes, nodeDomains, nodeQuadDomains); stringstream grpname; @@ -11547,7 +11547,7 @@ bool SMESH_MeshEditor::DoubleNodesOnGroupBoundaries( const std::vector, std::vector >::iterator ite = edgesMultiDomains.begin(); for (; ite != edgesMultiDomains.end(); ++ite) { - vector nodes = ite->first; + vector nodes = ite->first; vector orderDom = ite->second; vector orderedNodes; if (nodes.size() == 2) @@ -11584,10 +11584,9 @@ bool SMESH_MeshEditor::DoubleNodesOnGroupBoundaries( const std::vector, DownIdCompare> faceOrEdgeDom; // cellToModify --> (id domain --> id cell) std::map feDom; // vtk id of cell to modify --> id domain - faceOrEdgeDom.clear(); - feDom.clear(); //MESSAGE(".. Modification of elements"); + SMDSAbs_ElementType domainType = (*theElems[0].begin())->GetType(); for (int idomain = idom0; idomain < nbDomains; idomain++) { std::map >::const_iterator itnod = nodeDomains.begin(); @@ -11605,13 +11604,29 @@ bool SMESH_MeshEditor::DoubleNodesOnGroupBoundaries( const std::vectorGetParentVolumes(volParents, vtkId); + int nbvol = 0; + nbvol = grid->GetParentVolumes(volParents, vtkId); + if ( domainType == SMDSAbs_Volume ) + { + nbvol = grid->GetParentVolumes(volParents, vtkId); + } + else // domainType == SMDSAbs_Face + { + const int nbFaces = grid->getDownArray(vtkType)->getNumberOfUpCells(downId); + const int *upCells = grid->getDownArray(vtkType)->getUpCells(downId); + const unsigned char* upTypes = grid->getDownArray(vtkType)->getUpTypes(downId); + for (int i=0; i< nbFaces; i++) + { + int vtkFaceId = grid->getDownArray( upTypes[i] )->getVtkCellId(upCells[i]); + if (vtkFaceId >= 0) + volParents[nbvol++] = vtkFaceId; + } + } for (int j = 0; j < nbvol; j++) if (celldom.count(volParents[j]) && (celldom[volParents[j]] == idomain)) if (!feDom.count(vtkId)) { feDom[vtkId] = idomain; - faceOrEdgeDom[aCell] = emptyMap; faceOrEdgeDom[aCell][idomain] = vtkId; // affect face or edge to the first domain only //MESSAGE("affect cell " << this->GetMeshDS()->FromVtkToSmds(vtkId) << " domain " << idomain // << " type " << vtkType << " downId " << downId); @@ -11634,7 +11649,6 @@ bool SMESH_MeshEditor::DoubleNodesOnGroupBoundaries( const std::vectorfirst; std::set oldNodes; std::set::iterator itn; - oldNodes.clear(); grid->GetNodeIds(oldNodes, face.cellId, face.cellType); //MESSAGE("examine cell, downId " << face.cellId << " type " << int(face.cellType)); std::map localClonedNodeIds; @@ -11701,10 +11715,7 @@ bool SMESH_MeshEditor::CreateFlatElementsOnFacesGroups(const std::vector clonedNodes; std::map intermediateNodes; - clonedNodes.clear(); - intermediateNodes.clear(); std::map mapOfJunctionGroups; - mapOfJunctionGroups.clear(); for ( size_t idom = 0; idom < theElems.size(); idom++ ) { @@ -11951,7 +11962,6 @@ void SMESH_MeshEditor::CreateHoleSkin(double radius, std::set setOfVolToCheck; std::vector gpnts; - gpnts.clear(); if (isNodeGroup) // --- a group of nodes is provided : find all the volumes using one or more of this nodes { @@ -12038,7 +12048,6 @@ void SMESH_MeshEditor::CreateHoleSkin(double radius, // Fill the group of inside volumes std::map mapOfNodeDistance2; - mapOfNodeDistance2.clear(); std::set setOfOutsideVol; while (!setOfVolToCheck.empty()) { @@ -12215,9 +12224,7 @@ void SMESH_MeshEditor::CreateHoleSkin(double radius, // project polylines on subshapes, and partition, to get geom faces std::map > shapeIdToVtkIdSet; // shapeId --> set of vtkId on skin - std::set emptySet; - emptySet.clear(); - std::set shapeIds; + std::set shapeIds; SMDS_ElemIteratorPtr itelem = sgrps->GetElements(); while (itelem->more()) @@ -12227,7 +12234,6 @@ void SMESH_MeshEditor::CreateHoleSkin(double radius, int vtkId = elem->GetVtkID(); if (!shapeIdToVtkIdSet.count(shapeId)) { - shapeIdToVtkIdSet[shapeId] = emptySet; shapeIds.insert(shapeId); } shapeIdToVtkIdSet[shapeId].insert(vtkId); @@ -12235,7 +12241,6 @@ void SMESH_MeshEditor::CreateHoleSkin(double radius, std::map > shapeIdToEdges; // shapeId --> set of downward edges std::set emptyEdges; - emptyEdges.clear(); std::map >::iterator itShape = shapeIdToVtkIdSet.begin(); for (; itShape != shapeIdToVtkIdSet.end(); ++itShape) @@ -12278,7 +12283,6 @@ void SMESH_MeshEditor::CreateHoleSkin(double radius, } std::list order; - order.clear(); if (nodesEdges.size() > 0) { order.push_back(nodesEdges[0]); //MESSAGE(" --- back " << order.back()+1); // SMDS id = VTK id + 1; diff --git a/src/SMESH/SMESH_MesherHelper.cxx b/src/SMESH/SMESH_MesherHelper.cxx index 3b5483b13..1dcc5b064 100644 --- a/src/SMESH/SMESH_MesherHelper.cxx +++ b/src/SMESH/SMESH_MesherHelper.cxx @@ -658,10 +658,10 @@ gp_XY SMESH_MesherHelper::GetNodeUV(const TopoDS_Face& F, // corresponding EDGE from FACE, get pcurve for this // EDGE and retrieve value from this pcurve SMDS_EdgePositionPtr epos = pos; - const int edgeID = n->getshapeId(); - const TopoDS_Edge& E = TopoDS::Edge( GetMeshDS()->IndexToShape( edgeID )); + const int edgeID = n->getshapeId(); + const TopoDS_Edge& E = TopoDS::Edge( GetMeshDS()->IndexToShape( edgeID )); double f, l, u = epos->GetUParameter(); - Handle(Geom2d_Curve) C2d = BRep_Tool::CurveOnSurface( E, F, f, l ); + Handle(Geom2d_Curve) C2d = BRep_Tool::CurveOnSurface( E, F, f, l ); bool validU = ( !C2d.IsNull() && ( f < u ) && ( u < l )); if ( validU ) uv = C2d->Value( u ); else uv.SetCoord( Precision::Infinite(),0.); @@ -769,6 +769,17 @@ gp_XY SMESH_MesherHelper::GetNodeUV(const TopoDS_Face& F, if ( isSeam ) uv = getUVOnSeam( uv, GetNodeUV( F, n2, 0 )); } + else if ( myParIndex && n2 ) + { + gp_Pnt2d oldUV = uv; + gp_Pnt2d uv2 = GetNodeUV( F, n2, 0 ); + if ( myParIndex & 1 ) + uv.SetX( uv.X() + ShapeAnalysis::AdjustToPeriod( uv.X(), myPar1[0], myPar2[0])); + if ( myParIndex & 2 ) + uv.SetY( uv.Y() + ShapeAnalysis::AdjustToPeriod( uv.Y(), myPar1[1], myPar2[1])); + if ( uv.SquareDistance( uv2 ) > oldUV.SquareDistance( uv2 )) + uv = oldUV; + } } } else @@ -2724,33 +2735,30 @@ bool SMESH_MesherHelper::LoadNodeColumns(TParam2ColumnMap & theParam2 theParam2ColumnMap.begin()->second.size() == prevNbRows + expectNbRows ); } -namespace +//================================================================================ +/*! + * \brief Return true if a node is at a corner of a 2D structured mesh of FACE + */ +//================================================================================ + +bool SMESH_MesherHelper::IsCornerOfStructure( const SMDS_MeshNode* n, + const SMESHDS_SubMesh* faceSM, + SMESH_MesherHelper& faceAnalyser ) { - //================================================================================ - /*! - * \brief Return true if a node is at a corner of a 2D structured mesh of FACE - */ - //================================================================================ - - bool isCornerOfStructure( const SMDS_MeshNode* n, - const SMESHDS_SubMesh* faceSM, - SMESH_MesherHelper& faceAnalyser ) - { - int nbFacesInSM = 0; - if ( n ) { - SMDS_ElemIteratorPtr fIt = n->GetInverseElementIterator( SMDSAbs_Face ); - while ( fIt->more() ) - nbFacesInSM += faceSM->Contains( fIt->next() ); - } - if ( nbFacesInSM == 1 ) - return true; - - if ( nbFacesInSM == 2 && n->GetPosition()->GetTypeOfPosition() == SMDS_TOP_VERTEX ) - { - return faceAnalyser.IsRealSeam( n->getshapeId() ); - } - return false; + int nbFacesInSM = 0; + if ( n ) { + SMDS_ElemIteratorPtr fIt = n->GetInverseElementIterator( SMDSAbs_Face ); + while ( fIt->more() ) + nbFacesInSM += faceSM->Contains( fIt->next() ); } + if ( nbFacesInSM == 1 ) + return true; + + if ( nbFacesInSM == 2 && n->GetPosition()->GetTypeOfPosition() == SMDS_TOP_VERTEX ) + { + return faceAnalyser.IsRealSeam( n->getshapeId() ); + } + return false; } //======================================================================= @@ -2785,7 +2793,7 @@ bool SMESH_MesherHelper::IsStructured( SMESH_subMesh* faceSM ) int nbRemainEdges = nbEdgesInWires.front(); do { TopoDS_Vertex V = IthVertex( 0, edges.front() ); - isCorner = isCornerOfStructure( SMESH_Algo::VertexNode( V, meshDS ), + isCorner = IsCornerOfStructure( SMESH_Algo::VertexNode( V, meshDS ), fSM, faceAnalyser); if ( !isCorner ) { edges.splice( edges.end(), edges, edges.begin() ); @@ -2826,7 +2834,7 @@ bool SMESH_MesherHelper::IsStructured( SMESH_subMesh* faceSM ) for ( ; n != nodes.end(); ++n ) { ++nbEdges; - if ( isCornerOfStructure( *n, fSM, faceAnalyser )) { + if ( IsCornerOfStructure( *n, fSM, faceAnalyser )) { nbEdgesInSide.push_back( nbEdges ); nbEdges = 0; } diff --git a/src/SMESH/SMESH_MesherHelper.hxx b/src/SMESH/SMESH_MesherHelper.hxx index d48318877..82d242ec2 100644 --- a/src/SMESH/SMESH_MesherHelper.hxx +++ b/src/SMESH/SMESH_MesherHelper.hxx @@ -127,6 +127,13 @@ class SMESH_EXPORT SMESH_MesherHelper */ static bool IsStructured( SMESH_subMesh* faceSM ); + /*! + * \brief Return true if a node is at a corner of a 2D structured mesh of FACE + */ + static bool IsCornerOfStructure( const SMDS_MeshNode* n, + const SMESHDS_SubMesh* faceSM, + SMESH_MesherHelper& faceAnalyser ); + /*! * \brief Return true if 2D mesh on FACE is distored */ diff --git a/src/SMESHClient/CMakeLists.txt b/src/SMESHClient/CMakeLists.txt index ec1645696..ed7f14f47 100644 --- a/src/SMESHClient/CMakeLists.txt +++ b/src/SMESHClient/CMakeLists.txt @@ -26,6 +26,7 @@ INCLUDE_DIRECTORIES( ${Boost_INCLUDE_DIRS} ${OpenCASCADE_INCLUDE_DIR} ${OMNIORB_INCLUDE_DIR} + ${MEDCOUPLING_INCLUDE_DIRS} ${PROJECT_SOURCE_DIR}/src/Controls ${PROJECT_SOURCE_DIR}/src/Driver ${PROJECT_SOURCE_DIR}/src/DriverDAT diff --git a/src/SMESHDS/SMESHDS_Hypothesis.cxx b/src/SMESHDS/SMESHDS_Hypothesis.cxx index b88b3437d..712ab920d 100644 --- a/src/SMESHDS/SMESHDS_Hypothesis.cxx +++ b/src/SMESHDS/SMESHDS_Hypothesis.cxx @@ -114,3 +114,33 @@ bool SMESHDS_Hypothesis::IsSameName( const SMESHDS_Hypothesis& other) const { return _name == other._name; } + +//================================================================================ +/*! + * \brief Save a string to a stream + */ +//================================================================================ + +void SMESHDS_Hypothesis::SaveStringToStream(std::ostream & save, const std::string& txt ) +{ + save << " " << txt.size() << " " << txt; +} + +//================================================================================ +/*! + * \brief Load a string from a stream + */ +//================================================================================ + +bool SMESHDS_Hypothesis::LoadStringFromStream(std::istream & load, std::string& txt ) +{ + txt.clear(); + int size = -1; + if ( static_cast( load >> size ) && size > 0 ) + { + txt.resize( size, '\0' ); + load.get( txt[0] ); // remove a white-space + load.get( & txt[0], size + 1 ); + } + return (int)txt.size() == size; +} diff --git a/src/SMESHDS/SMESHDS_Hypothesis.hxx b/src/SMESHDS/SMESHDS_Hypothesis.hxx index 665cb9c13..5ecf50789 100644 --- a/src/SMESHDS/SMESHDS_Hypothesis.hxx +++ b/src/SMESHDS/SMESHDS_Hypothesis.hxx @@ -48,6 +48,9 @@ class SMESHDS_EXPORT SMESHDS_Hypothesis virtual std::ostream & SaveTo(std::ostream & save)=0; virtual std::istream & LoadFrom(std::istream & load)=0; + static void SaveStringToStream(std::ostream & save, const std::string& txt ); + static bool LoadStringFromStream(std::istream & load, std::string& txt ); + bool IsSameName( const SMESHDS_Hypothesis& other) const; virtual bool operator==(const SMESHDS_Hypothesis& other) const; bool operator!=(const SMESHDS_Hypothesis& other) const { return !(*this==other); } diff --git a/src/SMESHDS/SMESHDS_Mesh.cxx b/src/SMESHDS/SMESHDS_Mesh.cxx index df229269b..1396cdf21 100644 --- a/src/SMESHDS/SMESHDS_Mesh.cxx +++ b/src/SMESHDS/SMESHDS_Mesh.cxx @@ -56,14 +56,14 @@ class SMESHDS_Mesh::SubMeshHolder : public SMESHDS_TSubMeshHolder< const SMESHDS //======================================================================= //function : Create -//purpose : +//purpose : //======================================================================= SMESHDS_Mesh::SMESHDS_Mesh(int theMeshID, bool theIsEmbeddedMode): - myMeshID(theMeshID), mySubMeshHolder( new SubMeshHolder ), myIsEmbeddedMode(theIsEmbeddedMode) { myScript = new SMESHDS_Script(theIsEmbeddedMode); + SetPersistentId(theMeshID); } @@ -188,13 +188,15 @@ bool SMESHDS_Mesh::RemoveHypothesis(const TopoDS_Shape & S, //function : AddNode //purpose : //======================================================================= -SMDS_MeshNode* SMESHDS_Mesh::AddNode(double x, double y, double z){ +SMDS_MeshNode* SMESHDS_Mesh::AddNode(double x, double y, double z) +{ SMDS_MeshNode* node = SMDS_Mesh::AddNode(x, y, z); if(node!=NULL) myScript->AddNode(node->GetID(), x, y, z); return node; } -SMDS_MeshNode* SMESHDS_Mesh::AddNodeWithID(double x, double y, double z, smIdType ID){ +SMDS_MeshNode* SMESHDS_Mesh::AddNodeWithID(double x, double y, double z, smIdType ID) +{ SMDS_MeshNode* node = SMDS_Mesh::AddNodeWithID(x,y,z,ID); if(node!=NULL) myScript->AddNode(node->GetID(), x, y, z); return node; @@ -235,9 +237,8 @@ bool SMESHDS_Mesh::ChangeElementNodes(const SMDS_MeshElement * elem, //function : ChangePolygonNodes //purpose : //======================================================================= -bool SMESHDS_Mesh::ChangePolygonNodes -(const SMDS_MeshElement * elem, - std::vector nodes) +bool SMESHDS_Mesh::ChangePolygonNodes (const SMDS_MeshElement * elem, + std::vector& nodes) { ASSERT(nodes.size() > 3); @@ -255,14 +256,14 @@ bool SMESHDS_Mesh { ASSERT(nodes.size() > 3); + size_t i, len = nodes.size(); + std::vector nodes_ids( len ); + for ( i = 0; i < len; i++ ) + nodes_ids[i] = nodes[i]->GetID(); + if ( !SMDS_Mesh::ChangePolyhedronNodes( elem, nodes, quantities )) return false; - smIdType i, len = nodes.size(); - std::vector nodes_ids (len); - for (i = 0; i < len; i++) { - nodes_ids[i] = nodes[i]->GetID(); - } myScript->ChangePolyhedronNodes(elem->GetID(), nodes_ids, quantities); return true; diff --git a/src/SMESHDS/SMESHDS_Mesh.hxx b/src/SMESHDS/SMESHDS_Mesh.hxx index ed7852e65..814b3d450 100644 --- a/src/SMESHDS/SMESHDS_Mesh.hxx +++ b/src/SMESHDS/SMESHDS_Mesh.hxx @@ -595,8 +595,8 @@ class SMESHDS_EXPORT SMESHDS_Mesh : public SMDS_Mesh bool ChangeElementNodes(const SMDS_MeshElement * elem, const SMDS_MeshNode * nodes[], const int nbnodes); - bool ChangePolygonNodes(const SMDS_MeshElement * elem, - std::vector nodes); + bool ChangePolygonNodes(const SMDS_MeshElement * elem, + std::vector& nodes); bool ChangePolyhedronNodes(const SMDS_MeshElement * elem, const std::vector& nodes, const std::vector& quantities); @@ -656,7 +656,7 @@ class SMESHDS_EXPORT SMESHDS_Mesh : public SMDS_Mesh ShapeToHypothesis myShapeToHypothesis; - int myMeshID, myPersistentID; + int myPersistentID; TopoDS_Shape myShape; class SubMeshHolder; diff --git a/src/SMESHGUI/CMakeLists.txt b/src/SMESHGUI/CMakeLists.txt index e1696341b..587ee89bd 100644 --- a/src/SMESHGUI/CMakeLists.txt +++ b/src/SMESHGUI/CMakeLists.txt @@ -34,6 +34,7 @@ INCLUDE_DIRECTORIES( ${Boost_INCLUDE_DIRS} ${OMNIORB_INCLUDE_DIR} ${HDF5_INCLUDE_DIRS} + ${MEDCOUPLING_INCLUDE_DIRS} ${PROJECT_SOURCE_DIR}/src/OBJECT ${PROJECT_SOURCE_DIR}/src/SMESHFiltersSelection ${PROJECT_SOURCE_DIR}/src/SMDS diff --git a/src/SMESHGUI/SMESHGUI.cxx b/src/SMESHGUI/SMESHGUI.cxx index a68966e63..a4714beb7 100644 --- a/src/SMESHGUI/SMESHGUI.cxx +++ b/src/SMESHGUI/SMESHGUI.cxx @@ -460,6 +460,7 @@ namespace bool aCheckWarn = true; if ( resMgr ) aCheckWarn = resMgr->booleanValue( "SMESH", "show_warning", false ); + // get mesh object from selection and check duplication of their names bool hasDuplicatedMeshNames = false; QList< QPair< SMESH::SMESH_IDSource_var, QString > > aMeshList; @@ -628,8 +629,8 @@ namespace "SMESH_OCTAHEDRA","SMESH_POLYEDRONS","SMESH_QUADRATIC_POLYEDRONS","SMESH_BALLS" }; // is typeMsg complete? (compilation failure mains that enum SMDSAbs_EntityType changed) - const int nbTypes = sizeof( typeMsg ) / sizeof( const char* ); - int _assert[( nbTypes == SMESH::Entity_Last ) ? 2 : -1 ]; _assert[0]=_assert[1]=0; + static_assert( sizeof(typeMsg) / sizeof(const char*) == SMESH::Entity_Last, + "Update names of EntityType's!!!" ); QString andStr = " " + QObject::tr("SMESH_AND") + " ", comma(", "); for ( size_t iType = 0; iType < presentNotSupported.size(); ++iType ) { @@ -655,12 +656,11 @@ namespace // Init the parameters with the default values bool aIsASCII_STL = true; - bool toCreateGroups = false; - if ( resMgr ) - toCreateGroups = resMgr->booleanValue( "SMESH", "auto_groups", false ); - bool toOverwrite = true; - bool toFindOutDim = true; - double zTol = resMgr ? resMgr->doubleValue( "SMESH", "med_ztolerance", 0. ) : 0.; + bool toCreateGroups = resMgr->booleanValue( "SMESH", "auto_groups", false ); + bool toOverwrite = true; + bool toFindOutDim = true; + bool toRenumber = true; + double zTol = resMgr->doubleValue( "SMESH", "med_ztolerance", 0. ); QString aFilter, aTitle = QObject::tr("SMESH_EXPORT_MESH"); QString anInitialPath = ""; @@ -670,44 +670,46 @@ namespace QList< QPair< GEOM::ListOfFields_var, QString > > aFieldList; // Get a file name to write in and additional options - if ( isUNV || isDAT || isGMF ) // Export w/o options + if ( isGMF ) // Export w/o options { - if ( isUNV ) - aFilter = QObject::tr( "IDEAS_FILES_FILTER" ) + " (*.unv)"; - else if ( isDAT ) - aFilter = QObject::tr( "DAT_FILES_FILTER" ) + " (*.dat)"; - else if ( isGMF ) - aFilter = QObject::tr( "GMF_ASCII_FILES_FILTER" ) + " (*.mesh)" + - ";;" + QObject::tr( "GMF_BINARY_FILES_FILTER" ) + " (*.meshb)"; - if ( anInitialPath.isEmpty() ) anInitialPath = SUIT_FileDlg::getLastVisitedPath(); + aFilter = QObject::tr( "GMF_ASCII_FILES_FILTER" ) + " (*.mesh)" + + ";;" + QObject::tr( "GMF_BINARY_FILES_FILTER" ) + " (*.meshb)"; + if ( anInitialPath.isEmpty() ) anInitialPath = SUIT_FileDlg::getLastVisitedPath(); + aFilename = SUIT_FileDlg::getFileName(SMESHGUI::desktop(), anInitialPath + QString("/") + aMeshName, aFilter, aTitle, false); } - else if ( isCGNS )// Export to CGNS + else if ( isCGNS || isUNV || isDAT ) // Export to [ CGNS | UNV | DAT ] - one option { - const char* theByTypeResource = "cgns_group_elems_by_type"; - toCreateGroups = SMESHGUI::resourceMgr()->booleanValue( "SMESH", theByTypeResource, false ); + const char* theOptionResource = isCGNS ? "cgns_group_elems_by_type" : "export_renumber"; + bool option = resMgr->booleanValue( "SMESH", theOptionResource, false ); QStringList checkBoxes; - checkBoxes << QObject::tr("CGNS_EXPORT_ELEMS_BY_TYPE"); + checkBoxes << QObject::tr( isCGNS ? "CGNS_EXPORT_ELEMS_BY_TYPE" : "SMESH_RENUMBER" ); SalomeApp_CheckFileDlg* fd = new SalomeApp_CheckFileDlg ( SMESHGUI::desktop(), false, checkBoxes, true, true ); fd->setWindowTitle( aTitle ); - fd->setNameFilter( QObject::tr( "CGNS_FILES_FILTER" ) + " (*.cgns)" ); + if ( isCGNS ) + fd->setNameFilter( QObject::tr( "CGNS_FILES_FILTER" ) + " (*.cgns)" ); + else if ( isUNV ) + fd->setNameFilter( QObject::tr( "IDEAS_FILES_FILTER" ) + " (*.unv)" ); + else if ( isDAT ) + fd->setNameFilter( QObject::tr( "DAT_FILES_FILTER" ) + " (*.dat)" ); if ( !anInitialPath.isEmpty() ) fd->setDirectory( anInitialPath ); - fd->selectFile(aMeshName); + fd->selectFile( aMeshName ); SMESHGUI_FileValidator* fv = new SMESHGUI_FileValidator( fd ); fd->setValidator( fv ); - fd->SetChecked( toCreateGroups, 0 ); + fd->SetChecked( option, 0 ); if ( fd->exec() ) aFilename = fd->selectedFile(); - toOverwrite = fv->isOverwrite(aFilename); - toCreateGroups = fd->IsChecked(0); - SMESHGUI::resourceMgr()->setValue("SMESH", theByTypeResource, toCreateGroups ); + toOverwrite = fv->isOverwrite( aFilename ); + option = fd->IsChecked( 0 ); + SMESHGUI::resourceMgr()->setValue("SMESH", theOptionResource, option ); + ( isCGNS ? toCreateGroups : toRenumber ) = option; delete fd; } @@ -751,7 +753,6 @@ namespace for ( CORBA::ULong i = 0; i < mvok->length(); ++i ) { QString vs = (char*)( SMESH_Comment( mvok[i]/10 ) << "." << mvok[i]%10 ); - MESSAGE("MED version: " << vs.toStdString()); aFilterMap.insert( QObject::tr( "MED_VX_FILES_FILTER" ).arg( vs ) + " (*.med)", mvok[i]); } } @@ -924,9 +925,9 @@ namespace // if ( SMESHGUI::automaticUpdate() ) // SMESH::UpdateView(); // } - if ( isMED && isOkToWrite) + if ( isMED && isOkToWrite ) { - MESSAGE("OK to write MED file "<< aFilename.toUtf8().constData()); + const bool saveNumbers = resMgr->booleanValue( "SMESH", "med_save_numbers", true ); aMeshIter = aMeshList.begin(); for( int aMeshIndex = 0; aMeshIter != aMeshList.end(); aMeshIter++, aMeshIndex++ ) { @@ -934,15 +935,11 @@ namespace SMESH::SMESH_Mesh_var aMeshItem = aMeshOrGroup->GetMesh(); const GEOM::ListOfFields& fields = aFieldList[ aMeshIndex ].first.in(); const QString& geoAssFields = aFieldList[ aMeshIndex ].second; - const bool hasFields = ( fields.length() || !geoAssFields.isEmpty() ); - if ( !hasFields && aMeshOrGroup->_is_equivalent( aMeshItem ) && zTol < 0 ) - aMeshItem->ExportMED( aFilename.toUtf8().data(), toCreateGroups, aFormat, - toOverwrite && aMeshIndex == 0, toFindOutDim ); - else - aMeshItem->ExportPartToMED( aMeshOrGroup, aFilename.toUtf8().data(), - toCreateGroups, aFormat, - toOverwrite && aMeshIndex == 0, toFindOutDim, - fields, geoAssFields.toLatin1().data(), zTol ); + + aMeshItem->ExportPartToMED( aMeshOrGroup, aFilename.toUtf8().data(), + toCreateGroups, aFormat, + toOverwrite && aMeshIndex == 0, toFindOutDim, + fields, geoAssFields.toLatin1().data(), zTol, saveNumbers ); } } else if ( isSAUV ) @@ -957,16 +954,16 @@ namespace else if ( isDAT ) { if ( aMeshOrGroup->_is_equivalent( aMesh )) - aMesh->ExportDAT( aFilename.toUtf8().data() ); + aMesh->ExportDAT( aFilename.toUtf8().data(), toRenumber ); else - aMesh->ExportPartToDAT( aMeshOrGroup, aFilename.toUtf8().data() ); + aMesh->ExportPartToDAT( aMeshOrGroup, aFilename.toUtf8().data(), toRenumber ); } else if ( isUNV ) { if ( aMeshOrGroup->_is_equivalent( aMesh )) - aMesh->ExportUNV( aFilename.toUtf8().data() ); + aMesh->ExportUNV( aFilename.toUtf8().data(), toRenumber ); else - aMesh->ExportPartToUNV( aMeshOrGroup, aFilename.toUtf8().data() ); + aMesh->ExportPartToUNV( aMeshOrGroup, aFilename.toUtf8().data(), toRenumber ); } else if ( isSTL ) { @@ -1226,7 +1223,7 @@ namespace SMESH::Controls::NumericalFunctor* aNumFun = dynamic_cast( aFunctor.get() ); if ( aNumFun ) { - std::vector elements; + std::vector elements; SMESH::SMESH_Mesh_var mesh = SMESH::IObjectToInterface(anIO); if ( mesh->_is_nil() ) { SMESH::SMESH_IDSource_var idSource = @@ -5479,6 +5476,7 @@ void SMESHGUI::createPreferences() setPreferenceProperty( exportgroup, "columns", 2 ); addPreference( tr( "PREF_AUTO_GROUPS" ), exportgroup, LightApp_Preferences::Bool, "SMESH", "auto_groups" ); addPreference( tr( "PREF_SHOW_WARN" ), exportgroup, LightApp_Preferences::Bool, "SMESH", "show_warning" ); + addPreference( tr( "PREF_MED_SAVE_NUMS" ), exportgroup, LightApp_Preferences::Bool, "SMESH", "med_save_numbers" ); int zTol = addPreference( tr( "PREF_ZTOLERANCE" ), exportgroup, LightApp_Preferences::DblSpin, "SMESH", "med_ztolerance" ); setPreferenceProperty( zTol, "precision", 10 ); setPreferenceProperty( zTol, "min", 0.0000000001 ); diff --git a/src/SMESHGUI/SMESHGUI_IdPreview.cxx b/src/SMESHGUI/SMESHGUI_IdPreview.cxx index 4b591481a..fd7df6000 100644 --- a/src/SMESHGUI/SMESHGUI_IdPreview.cxx +++ b/src/SMESHGUI/SMESHGUI_IdPreview.cxx @@ -22,8 +22,11 @@ #include "SMESHGUI_IdPreview.h" -#include #include + +#include +#include +#include #include #include @@ -71,21 +74,27 @@ SMESHGUI_IdPreview::SMESHGUI_IdPreview(SVTK_ViewWindow* theViewWindow): myPtsSelectVisiblePoints->SetInputConnection(myPtsMaskPoints->GetOutputPort()); myPtsSelectVisiblePoints->SelectInvisibleOff(); myPtsSelectVisiblePoints->SetTolerance(0.1); - + myPtsLabeledDataMapper = vtkLabeledDataMapper::New(); myPtsLabeledDataMapper->SetInputConnection(myPtsSelectVisiblePoints->GetOutputPort()); myPtsLabeledDataMapper->SetLabelModeToLabelScalars(); - + vtkTextProperty* aPtsTextProp = vtkTextProperty::New(); aPtsTextProp->SetFontFamilyToTimes(); - static int aPointsFontSize = 12; + int aPointsFontSize = 12; + if ( SUIT_ResourceMgr* mgr = SUIT_Session::session()->resourceMgr() ) + if ( mgr->hasValue( "SMESH", "numbering_node_font" ) ) + { + QFont f = mgr->fontValue( "SMESH", "numbering_node_font" ); + aPointsFontSize = f.pointSize(); + } aPtsTextProp->SetFontSize(aPointsFontSize); aPtsTextProp->SetBold(1); aPtsTextProp->SetItalic(0); aPtsTextProp->SetShadow(0); myPtsLabeledDataMapper->SetLabelTextProperty(aPtsTextProp); aPtsTextProp->Delete(); - + myIsPointsLabeled = false; myPointLabels = vtkActor2D::New(); diff --git a/src/SMESHGUI/SMESHGUI_IdPreview.h b/src/SMESHGUI/SMESHGUI_IdPreview.h index bb7e18a2f..dd87a7caf 100644 --- a/src/SMESHGUI/SMESHGUI_IdPreview.h +++ b/src/SMESHGUI/SMESHGUI_IdPreview.h @@ -47,7 +47,7 @@ class vtkUnstructuredGrid; /*! * \brief To display in the viewer IDs of selected elements or nodes */ -class SMESHGUI_IdPreview +class SMESHGUI_EXPORT SMESHGUI_IdPreview { public: SMESHGUI_IdPreview(SVTK_ViewWindow* theViewWindow); diff --git a/src/SMESHGUI/SMESHGUI_MeshDlg.cxx b/src/SMESHGUI/SMESHGUI_MeshDlg.cxx index f61406d59..cc8b4b2e7 100644 --- a/src/SMESHGUI/SMESHGUI_MeshDlg.cxx +++ b/src/SMESHGUI/SMESHGUI_MeshDlg.cxx @@ -891,6 +891,7 @@ void SMESHGUI_MeshDlg::setAvailableMeshType( const QStringList& theTypeMesh ) { myMeshType->clear(); myMeshType->addItems(theTypeMesh); + myMeshType->setEnabled( theTypeMesh.size() > 1 ); } //================================================================================ /*! diff --git a/src/SMESHGUI/SMESHGUI_Utils.h b/src/SMESHGUI/SMESHGUI_Utils.h index 6405448b1..9515099b7 100644 --- a/src/SMESHGUI/SMESHGUI_Utils.h +++ b/src/SMESHGUI/SMESHGUI_Utils.h @@ -106,12 +106,12 @@ SMESHGUI_EXPORT _PTR(SObject) FindSObject( CORBA::Object_ptr ); SMESHGUI_EXPORT - void SetName( _PTR(SObject), const QString& ); + void SetName( _PTR(SObject), const QString& name ); SMESHGUI_EXPORT - void SetValue( _PTR(SObject), const QString& ); - void setFileType( _PTR(SObject), const QString& ); - void setFileName( _PTR(SObject), const QString& ); + void SetValue ( _PTR(SObject), const QString& value ); + void setFileType( _PTR(SObject), const QString& fileType ); + void setFileName( _PTR(SObject), const QString& fileName ); SMESHGUI_EXPORT CORBA::Object_var SObjectToObject( _PTR(SObject) ); @@ -141,7 +141,7 @@ SMESHGUI_EXPORT } SMESHGUI_EXPORT - CORBA::Object_var IORToObject( const QString& ); + CORBA::Object_var IORToObject( const QString& ior ); template typename TInterface::_var_type IORToInterface( const QString& theIOR ) @@ -153,7 +153,7 @@ SMESHGUI_EXPORT } SMESHGUI_EXPORT - CORBA::Object_var EntryToObject( const QString& ); + CORBA::Object_var EntryToObject( const QString& entry ); template typename TInterface::_var_type EntryToInterface( const QString& theEntry ) @@ -165,7 +165,7 @@ SMESHGUI_EXPORT } SMESHGUI_EXPORT - int GetNameOfSelectedIObjects( LightApp_SelectionMgr*, QString& ); + int GetNameOfSelectedIObjects( LightApp_SelectionMgr*, QString& name ); SMESHGUI_EXPORT QString GetName( const Handle(SALOME_InteractiveObject)& theIO ); @@ -174,7 +174,7 @@ SMESHGUI_EXPORT _PTR(SObject) GetMeshOrSubmesh( _PTR(SObject) ); SMESHGUI_EXPORT - void ShowHelpFile( const QString& ); + void ShowHelpFile( const QString& helpFileName); /*! * \brief Return the normal to a face diff --git a/src/SMESHGUI/SMESHGUI_VTKUtils.cxx b/src/SMESHGUI/SMESHGUI_VTKUtils.cxx index eb7a7e5bf..e3d6adeab 100644 --- a/src/SMESHGUI/SMESHGUI_VTKUtils.cxx +++ b/src/SMESHGUI/SMESHGUI_VTKUtils.cxx @@ -1226,8 +1226,8 @@ namespace SMESH int GetEdgeNodes(SVTK_Selector* theSelector, const TVisualObjPtr& theVisualObject, - smIdType& theId1, - smIdType& theId2) + ::smIdType& theId1, + ::smIdType& theId2) { const SALOME_ListIO& selected = theSelector->StoredIObjects(); @@ -1243,9 +1243,9 @@ namespace SMESH if ( aMapIndex.Extent() != 2 ) return -1; - smIdType anObjId = -1, anEdgeNum = -1; - for ( smIdType i = 1; i <= aMapIndex.Extent(); i++ ) { - smIdType aVal = aMapIndex( i ); + ::smIdType anObjId = -1, anEdgeNum = -1; + for ( ::smIdType i = 1; i <= aMapIndex.Extent(); i++ ) { + ::smIdType aVal = aMapIndex( i ); if ( aVal > 0 ) anObjId = aVal; else @@ -1343,7 +1343,7 @@ namespace SMESH } - int GetEdgeNodes( LightApp_SelectionMgr* theMgr, smIdType& theId1, smIdType& theId2 ) + int GetEdgeNodes( LightApp_SelectionMgr* theMgr, ::smIdType& theId1, ::smIdType& theId2 ) { SALOME_ListIO selected; theMgr->selectedObjects( selected ); @@ -1363,9 +1363,9 @@ namespace SMESH if ( aMapIndex.Extent() != 2 ) return -1; - smIdType anObjId = -1, anEdgeNum = -1; - for ( smIdType i = 1; i <= aMapIndex.Extent(); i++ ) { - smIdType aVal = aMapIndex( i ); + ::smIdType anObjId = -1, anEdgeNum = -1; + for ( ::smIdType i = 1; i <= aMapIndex.Extent(); i++ ) { + ::smIdType aVal = aMapIndex( i ); if ( aVal > 0 ) anObjId = aVal; else diff --git a/src/SMESHGUI/SMESHGUI_VTKUtils.h b/src/SMESHGUI/SMESHGUI_VTKUtils.h index dec7bdc65..1adcd5c56 100644 --- a/src/SMESHGUI/SMESHGUI_VTKUtils.h +++ b/src/SMESHGUI/SMESHGUI_VTKUtils.h @@ -169,7 +169,7 @@ SMESHGUI_EXPORT const Handle(SALOME_InteractiveObject)&, QString& ); SMESHGUI_EXPORT - int GetEdgeNodes( SVTK_Selector*, const TVisualObjPtr&, smIdType&, smIdType& ); + int GetEdgeNodes( SVTK_Selector*, const TVisualObjPtr&, ::smIdType&, ::smIdType& ); //---------------------------------------------------------------------------- SMESHGUI_EXPORT @@ -189,7 +189,7 @@ SMESHGUI_EXPORT const bool = true ); SMESHGUI_EXPORT - int GetEdgeNodes( LightApp_SelectionMgr*, smIdType&, smIdType& ); + int GetEdgeNodes( LightApp_SelectionMgr*, ::smIdType&, ::smIdType& ); SMESHGUI_EXPORT void SetControlsPrecision( const long ); diff --git a/src/SMESHGUI/SMESH_msg_en.ts b/src/SMESHGUI/SMESH_msg_en.ts index 32fb70b88..a4b6cfd7a 100644 --- a/src/SMESHGUI/SMESH_msg_en.ts +++ b/src/SMESHGUI/SMESH_msg_en.ts @@ -2840,6 +2840,10 @@ Check algorithm documentation for supported geometry SMESH_RENUMBERING Renumbering + + SMESH_RENUMBER + Renumber + SMESH_RENUMBERING_ELEMENTS_TITLE Renumbering elements @@ -4885,6 +4889,10 @@ Please, create VTK viewer and try again PREF_SHOW_WARN Show warning when exporting group + + PREF_MED_SAVE_NUMS + Save cell/node numbers to MED file + PREF_ZTOLERANCE Z tolerance for MED export diff --git a/src/SMESHUtils/CMakeLists.txt b/src/SMESHUtils/CMakeLists.txt index 652f469de..8eb4e3b68 100644 --- a/src/SMESHUtils/CMakeLists.txt +++ b/src/SMESHUtils/CMakeLists.txt @@ -61,6 +61,7 @@ SET(SMESHUtils_HEADERS SMESH_ControlPnt.hxx SMESH_Delaunay.hxx SMESH_Indexer.hxx + SMESH_BoostTxtArchive.hxx ) # --- sources --- @@ -84,6 +85,7 @@ SET(SMESHUtils_SOURCES SMESH_Offset.cxx SMESH_Slot.cxx SMESH_PolyLine.cxx + SMESH_BoostTxtArchive.cxx ) # --- rules --- diff --git a/src/SMESHUtils/SMESH_BoostTxtArchive.cxx b/src/SMESHUtils/SMESH_BoostTxtArchive.cxx new file mode 100644 index 000000000..9e29c5479 --- /dev/null +++ b/src/SMESHUtils/SMESH_BoostTxtArchive.cxx @@ -0,0 +1,152 @@ +// Copyright (C) 2007-2021 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// +// File : SMESH_BoostTxtArchive.cxx +// Created : Thu Aug 5 21:19:31 2021 +// Author : Edward AGAPOV (eap) + +#include "SMESH_BoostTxtArchive.hxx" + +#include +#include +#include + + +using namespace SMESHUtils; + +BoostTxtArchive::BoostTxtArchive( const std::string& s ): + myArchiveReader( nullptr ), + myString( s ), + myStringFixed( false ), + myStream( nullptr ), + myOwnStream( true ) +{ + myStream = new std::istringstream( myString ); + makeReader(); +} + +BoostTxtArchive::BoostTxtArchive( std::istream& stream ): + myArchiveReader( nullptr ), + myStringFixed( false ), + myStream( &stream ), + myOwnStream( false ) +{ + if ( std::istringstream * sstrm = dynamic_cast< std::istringstream* >( &stream )) + myString = sstrm->str(); + + makeReader(); +} + +BoostTxtArchive::~BoostTxtArchive() +{ + delete myArchiveReader; myArchiveReader = nullptr; + if ( myOwnStream ) + delete myStream; +} + +void BoostTxtArchive::makeReader() +{ + myArchiveReader = nullptr; + try + { + myArchiveReader = new boost::archive::text_iarchive( *myStream ); + } + catch (...) + { + if ( fixString() ) + try + { + myArchiveReader = new boost::archive::text_iarchive( *myStream ); + } + catch(...) + { + myArchiveReader = nullptr; + } + } +} + +namespace +{ + //================================================================================ + /*! + * \brief Return archive created by current version of boost::archive + */ + //================================================================================ + + std::string getCurrentVersionArchive( BoostTxtArchive & bta) + { + std::ostringstream strm; + boost::archive::text_oarchive archive( strm ); + archive << bta; + return strm.str(); + } +} + +//================================================================================ +/*! + * \brief Change boost::archive library version in myString to be equal to + * the current library version + * \return bool - return true if the version is changed + */ +//================================================================================ + +bool BoostTxtArchive::fixString() +{ + if ( myStringFixed ) + return false; + myStringFixed = true; + + const char* sub = "serialization::archive "; + const size_t subLen = 23; + + size_t where1 = myString.find( sub ); + if ( where1 == std::string::npos ) + return false; + + std::string nowString = getCurrentVersionArchive( *this ); + size_t where2 = nowString.find( sub ); + if ( where2 == std::string::npos ) + return false; + + bool sameVersion = true; + for ( size_t i1 = where1 + subLen, i2 = where2 + subLen; + i2 < nowString.size(); + ++i1, ++i2 ) + { + if ( myString[ i1 ] != nowString[ i2 ] ) + { + sameVersion = false; + myString[ i1 ] = nowString[ i2 ]; + } + if ( isspace( myString[ i1 ])) + break; + } + + if ( !sameVersion ) + { + if ( myOwnStream ) + delete myStream; + myStream = new std::istringstream( myString ); + myOwnStream = true; + } + + return !sameVersion; +} diff --git a/src/SMESHUtils/SMESH_BoostTxtArchive.hxx b/src/SMESHUtils/SMESH_BoostTxtArchive.hxx new file mode 100644 index 000000000..cb5071f69 --- /dev/null +++ b/src/SMESHUtils/SMESH_BoostTxtArchive.hxx @@ -0,0 +1,95 @@ +// Copyright (C) 2007-2021 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// +// File : SMESH_BoostTxtArchive.hxx +// Created : Thu Aug 5 19:10:24 2021 +// Author : Edward AGAPOV (eap) + + +#ifndef __SMESH_BoostTxtArchive_HXX__ +#define __SMESH_BoostTxtArchive_HXX__ + +#include "SMESH_Utils.hxx" + +#include + +namespace SMESHUtils +{ + /*! + * \brief Load an object from a string created by boost::archive::text_oarchive. + * + * Try to workaround the issue that loading fails if the archive string + * is created by a newer version of boost::archive library. + * + * Usage: ObjType obj; BoostTxtArchive( arcString ) >> obj; + */ + class SMESHUtils_EXPORT BoostTxtArchive + { + public: + + BoostTxtArchive( const std::string& s ); + BoostTxtArchive( std::istream& stream ); + ~BoostTxtArchive(); + + template< class T > + BoostTxtArchive & operator>>( T & t ) + { + if ( myArchiveReader ) + try + { + (*myArchiveReader) >> t; + } + catch (...) + { + if ( fixString() ) + try + { + (*myArchiveReader) >> t; + } + catch(...) + { + } + } + return *this; + } + + private: + + void makeReader(); + bool fixString(); + + boost::archive::text_iarchive* myArchiveReader; + std::string myString; // archive to read + bool myStringFixed; // is archive version changed + std::istream* myStream; // stream holding myString + bool myOwnStream; // is myStream created by me + + // persistence used to create a current version archive + friend class boost::serialization::access; + template + void serialize(Archive & /*ar*/, const unsigned int /*version*/) + { + } + }; +} + + +#endif diff --git a/src/SMESHUtils/SMESH_Delaunay.cxx b/src/SMESHUtils/SMESH_Delaunay.cxx index bc5576797..610d7d09b 100644 --- a/src/SMESHUtils/SMESH_Delaunay.cxx +++ b/src/SMESHUtils/SMESH_Delaunay.cxx @@ -273,7 +273,7 @@ const BRepMesh_Triangle* SMESH_Delaunay::GetTriangleNear( int iBndNode ) if ( iBndNode >= _triaDS->NbNodes() ) return 0; int nodeIDs[3]; - int nbNbNodes = _bndNodes.size(); + int nbBndNodes = _bndNodes.size(); #if OCC_VERSION_LARGE <= 0x07030000 typedef BRepMesh::ListOfInteger TLinkList; #else @@ -289,9 +289,9 @@ const BRepMesh_Triangle* SMESH_Delaunay::GetTriangleNear( int iBndNode ) if ( tria.Movability() != BRepMesh_Deleted ) { _triaDS->ElementNodes( tria, nodeIDs ); - if ( nodeIDs[0]-1 < nbNbNodes && - nodeIDs[1]-1 < nbNbNodes && - nodeIDs[2]-1 < nbNbNodes ) + if ( nodeIDs[0]-1 < nbBndNodes && + nodeIDs[1]-1 < nbBndNodes && + nodeIDs[2]-1 < nbBndNodes ) return &tria; } } @@ -301,9 +301,9 @@ const BRepMesh_Triangle* SMESH_Delaunay::GetTriangleNear( int iBndNode ) if ( tria.Movability() != BRepMesh_Deleted ) { _triaDS->ElementNodes( tria, nodeIDs ); - if ( nodeIDs[0]-1 < nbNbNodes && - nodeIDs[1]-1 < nbNbNodes && - nodeIDs[2]-1 < nbNbNodes ) + if ( nodeIDs[0]-1 < nbBndNodes && + nodeIDs[1]-1 < nbBndNodes && + nodeIDs[2]-1 < nbBndNodes ) return &tria; } } @@ -373,14 +373,29 @@ void SMESH_Delaunay::ToPython() const } int nodeIDs[3]; + const char* dofName[] = { "Free", + "InVolume", + "OnSurface", + "OnCurve", + "Fixed", + "Frontier", + "Deleted" }; + text << "# nb elements = " << _triaDS->NbElements() << endl; + std::vector< int > deletedElems; for ( int i = 0; i < _triaDS->NbElements(); ++i ) { const BRepMesh_Triangle& t = _triaDS->GetElement( i+1 ); if ( t.Movability() == BRepMesh_Deleted ) - continue; + deletedElems.push_back( i+1 ); + // continue; _triaDS->ElementNodes( t, nodeIDs ); - text << "mesh.AddFace([ " << nodeIDs[0] << ", " << nodeIDs[1] << ", " << nodeIDs[2] << " ])" << endl; + text << "mesh.AddFace([ " << nodeIDs[0] << ", " << nodeIDs[1] << ", " << nodeIDs[2] << " ]) # " + << dofName[ t.Movability() ] << endl; } + text << "mesh.MakeGroupByIds( 'deleted elements', SMESH.FACE, ["; + for ( int id : deletedElems ) + text << id << ","; + text << "])" << endl; const char* fileName = "/tmp/Delaunay.py"; SMESH_File file( fileName, false ); diff --git a/src/SMESHUtils/SMESH_File.cxx b/src/SMESHUtils/SMESH_File.cxx index 86723df99..1e249c430 100644 --- a/src/SMESHUtils/SMESH_File.cxx +++ b/src/SMESHUtils/SMESH_File.cxx @@ -81,12 +81,12 @@ bool SMESH_File::open() if ( !_map && length > 0 ) { #ifdef WIN32 -#ifdef UNICODE +# ifdef UNICODE std::wstring aName = Kernel_Utils::utf8_decode_s(_name); const wchar_t* name = aName.c_str(); -#else +# else char* name = _name.data(); -#endif +# endif _file = CreateFile(name, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); bool ok = ( _file != INVALID_HANDLE_VALUE ); diff --git a/src/SMESHUtils/SMESH_TryCatch.cxx b/src/SMESHUtils/SMESH_TryCatch.cxx index 4552a1e7f..48ebcdee2 100644 --- a/src/SMESHUtils/SMESH_TryCatch.cxx +++ b/src/SMESHUtils/SMESH_TryCatch.cxx @@ -39,6 +39,15 @@ const char* SMESH::returnError(const char* txt) return txt; } +void SMESH::printErrorInDebugMode(const char* txt) +{ +#ifdef _DEBUG_ + std::cerr << txt << " " << __FILE__ << ": " << __LINE__ << std::endl; +#else + (void)txt; // unused in release mode +#endif +} + // ------------------------------------------------------------------ #include "SMESH_ComputeError.hxx" diff --git a/src/SMESHUtils/SMESH_TryCatch.hxx b/src/SMESHUtils/SMESH_TryCatch.hxx index 5abfac368..7c195c379 100644 --- a/src/SMESHUtils/SMESH_TryCatch.hxx +++ b/src/SMESHUtils/SMESH_TryCatch.hxx @@ -66,7 +66,7 @@ //------------------------------------------------------------------------------------- // A macro makes description of a caught exception and calls onExceptionFun(const char*). // Several onExceptionFun() are defined here: throwSalomeEx(), doNothing() and returnError(). -// To add your own catch close, define SMY_OWN_CATCH macro before including this file. +// To add your own catch clause, define SMY_OWN_CATCH macro before including this file. #define SMESH_CATCH( onExceptionFun ) \ } \ @@ -108,6 +108,7 @@ namespace SMESH SMESHUtils_EXPORT void throwSalomeEx(const char* txt); SMESHUtils_EXPORT void doNothing(const char* txt); SMESHUtils_EXPORT const char* returnError(const char* txt); + SMESHUtils_EXPORT void printErrorInDebugMode(const char* txt); } #endif diff --git a/src/SMESHUtils/SMESH_TypeDefs.hxx b/src/SMESHUtils/SMESH_TypeDefs.hxx index f6fcdb505..a682b894d 100644 --- a/src/SMESHUtils/SMESH_TypeDefs.hxx +++ b/src/SMESHUtils/SMESH_TypeDefs.hxx @@ -104,6 +104,8 @@ namespace SMESHUtils TOBJ* _obj; ArrayDeleter( TOBJ* obj ): _obj( obj ) {} ~ArrayDeleter() { delete [] _obj; _obj = 0; } + operator TOBJ*() { return _obj; } + TOBJ* get() { return _obj; } private: ArrayDeleter( const ArrayDeleter& ); }; diff --git a/src/SMESH_I/CMakeLists.txt b/src/SMESH_I/CMakeLists.txt index dc500e2c7..e04e4a604 100644 --- a/src/SMESH_I/CMakeLists.txt +++ b/src/SMESH_I/CMakeLists.txt @@ -28,6 +28,7 @@ INCLUDE_DIRECTORIES( ${KERNEL_INCLUDE_DIRS} ${GUI_INCLUDE_DIRS} ${GEOM_INCLUDE_DIRS} + ${MEDCOUPLING_INCLUDE_DIRS} ${PROJECT_SOURCE_DIR}/src/Controls ${PROJECT_SOURCE_DIR}/src/SMDS ${PROJECT_SOURCE_DIR}/src/SMESHDS diff --git a/src/SMESH_I/SMESH_Component_Generator.cxx b/src/SMESH_I/SMESH_Component_Generator.cxx index a1819c5e1..0a1a1d9c2 100644 --- a/src/SMESH_I/SMESH_Component_Generator.cxx +++ b/src/SMESH_I/SMESH_Component_Generator.cxx @@ -23,6 +23,8 @@ #include "SALOME_Container_i.hxx" #include "SALOME_KernelServices.hxx" +#include "SALOME_Fake_NamingService.hxx" + #include static Engines::EngineComponent_var _unique_compo; @@ -41,11 +43,13 @@ Engines::EngineComponent_var RetrieveSMESHInstance() PortableServer::POAManager_var pman = poa->the_POAManager(); CORBA::PolicyList policies; policies.length(0); - Engines_Container_i *cont(KERNEL::getContainerSA()); + auto *cont(KERNEL::getContainerSA()); PortableServer::ObjectId *conId(cont->getCORBAId()); // pman->activate(); // + SMESH_Gen_i::SetNS(new SALOME_Fake_NamingService); + // SMESH_Gen_No_Session_i *servant = new SMESH_Gen_No_Session_i(orb, poa, conId, "SMESH_inst_2", "SMESH"); PortableServer::ObjectId *zeId = servant->getId(); CORBA::Object_var zeRef = poa->id_to_reference(*zeId); diff --git a/src/SMESH_I/SMESH_Filter_i.cxx b/src/SMESH_I/SMESH_Filter_i.cxx index 2429d5fc1..954f98cd8 100644 --- a/src/SMESH_I/SMESH_Filter_i.cxx +++ b/src/SMESH_I/SMESH_Filter_i.cxx @@ -60,8 +60,8 @@ #include #include -using namespace SMESH; -using namespace SMESH::Controls; +//using namespace SMESH; +//using namespace SMESH::Controls; namespace SMESH @@ -79,9 +79,9 @@ namespace SMESH inline const SMDS_Mesh* -MeshPtr2SMDSMesh( SMESH_Mesh_ptr theMesh ) +MeshPtr2SMDSMesh( SMESH::SMESH_Mesh_ptr theMesh ) { - SMESH_Mesh_i* anImplPtr = DownCast(theMesh); + SMESH_Mesh_i* anImplPtr = SMESH::DownCast(theMesh); return anImplPtr ? anImplPtr->GetImpl().GetMeshDS() : 0; } @@ -117,11 +117,11 @@ static SMESH::Filter::Criterion createCriterion() { SMESH::Filter::Criterion aCriterion; - aCriterion.Type = FT_Undefined; - aCriterion.Compare = FT_Undefined; + aCriterion.Type = SMESH::FT_Undefined; + aCriterion.Compare = SMESH::FT_Undefined; aCriterion.Threshold = 0; - aCriterion.UnaryOp = FT_Undefined; - aCriterion.BinaryOp = FT_Undefined; + aCriterion.UnaryOp = SMESH::FT_Undefined; + aCriterion.BinaryOp = SMESH::FT_Undefined; aCriterion.ThresholdStr = ""; aCriterion.ThresholdID = ""; aCriterion.Tolerance = Precision::Confusion(); @@ -181,2309 +181,13 @@ static TopoDS_Shape getShapeByID (const char* theID) FUNCTORS */ -/* - Class : Functor_i - Description : An abstract class for all functors -*/ -Functor_i::Functor_i(): - SALOME::GenericObj_i( SMESH_Gen_i::GetPOA() ) -{ - //Base class Salome_GenericObject do it inmplicitly by overriding PortableServer::POA_ptr _default_POA() method - //PortableServer::ObjectId_var anObjectId = - // SMESH_Gen_i::GetPOA()->activate_object( this ); -} - -Functor_i::~Functor_i() -{ - //TPythonDump()<SetMesh( MeshPtr2SMDSMesh( theMesh ) ); - TPythonDump()<GetType(); -} - - -/* - Class : NumericalFunctor_i - Description : Base class for numerical functors -*/ -CORBA::Double NumericalFunctor_i::GetValue( SMESH::smIdType theId ) -{ - return myNumericalFunctorPtr->GetValue( theId ); -} - -CORBA::Boolean NumericalFunctor_i::IsApplicable( SMESH::smIdType theElementId ) -{ - return myNumericalFunctorPtr->IsApplicable( theElementId ); -} - -SMESH::Histogram* NumericalFunctor_i::GetHistogram(CORBA::Short nbIntervals, CORBA::Boolean isLogarithmic) -{ - std::vector nbEvents; - std::vector funValues; - std::vector elements; - myNumericalFunctorPtr->GetHistogram(nbIntervals,nbEvents,funValues,elements,0,isLogarithmic); - - SMESH::Histogram_var histogram = new SMESH::Histogram; - - nbIntervals = CORBA::Short( Min( int( nbEvents.size()), - int( funValues.size() - 1 ))); - if ( nbIntervals > 0 ) - { - histogram->length( nbIntervals ); - for ( int i = 0; i < nbIntervals; ++i ) - { - HistogramRectangle& rect = histogram[i]; - rect.nbEvents = nbEvents[i]; - rect.min = funValues[i]; - rect.max = funValues[i+1]; - } - } - return histogram._retn(); -} - -SMESH::Histogram* NumericalFunctor_i::GetLocalHistogram(CORBA::Short nbIntervals, - CORBA::Boolean isLogarithmic, - SMESH::SMESH_IDSource_ptr object) -{ - SMESH::Histogram_var histogram = new SMESH::Histogram; - - std::vector nbEvents; - std::vector funValues; - std::vector elements; - - SMDS_ElemIteratorPtr elemIt; - if ( SMESH::DownCast< SMESH_GroupOnFilter_i* >( object ) || - SMESH::DownCast< SMESH::Filter_i* >( object )) - { - elemIt = SMESH_Mesh_i::GetElements( object, GetElementType() ); - if ( !elemIt ) return histogram._retn(); - } - else - { - SMESH::SMESH_Mesh_var mesh = object->GetMesh(); - SMESH::smIdType_array_var objNbElems = object->GetNbElementsByType(); - SMESH::smIdType_array_var meshNbElems = mesh-> GetNbElementsByType(); - if ( meshNbElems[ GetElementType() ] != - objNbElems [ GetElementType() ] ) - { - elements.reserve( objNbElems[ GetElementType() ]); - elemIt = SMESH_Mesh_i::GetElements( object, GetElementType() ); - } - } - if ( elemIt ) - { - while ( elemIt->more() ) - elements.push_back( elemIt->next()->GetID() ); - if ( elements.empty() ) return histogram._retn(); - } - - myNumericalFunctorPtr->GetHistogram(nbIntervals,nbEvents,funValues,elements,0,isLogarithmic); - - nbIntervals = CORBA::Short( Min( int( nbEvents.size()), - int( funValues.size() - 1 ))); - if ( nbIntervals > 0 ) - { - histogram->length( nbIntervals ); - for ( int i = 0; i < nbIntervals; ++i ) - { - HistogramRectangle& rect = histogram[i]; - rect.nbEvents = nbEvents[i]; - rect.min = funValues[i]; - rect.max = funValues[i+1]; - } - } - return histogram._retn(); -} - -void NumericalFunctor_i::SetPrecision( CORBA::Long thePrecision ) -{ - myNumericalFunctorPtr->SetPrecision( thePrecision ); - TPythonDump()<GetPrecision(); -} - -Controls::NumericalFunctorPtr NumericalFunctor_i::GetNumericalFunctor() -{ - return myNumericalFunctorPtr; -} - - -/* - Class : SMESH_MinimumAngle - Description : Functor for calculation of minimum angle -*/ -MinimumAngle_i::MinimumAngle_i() -{ - myNumericalFunctorPtr.reset( new Controls::MinimumAngle() ); - myFunctorPtr = myNumericalFunctorPtr; -} - -FunctorType MinimumAngle_i::GetFunctorType() -{ - return SMESH::FT_MinimumAngle; -} - - -/* - Class : AspectRatio - Description : Functor for calculating aspect ratio -*/ -AspectRatio_i::AspectRatio_i() -{ - myNumericalFunctorPtr.reset( new Controls::AspectRatio() ); - myFunctorPtr = myNumericalFunctorPtr; -} - -FunctorType AspectRatio_i::GetFunctorType() -{ - return SMESH::FT_AspectRatio; -} - - -/* - Class : AspectRatio3D - Description : Functor for calculating aspect ratio 3D -*/ -AspectRatio3D_i::AspectRatio3D_i() -{ - myNumericalFunctorPtr.reset( new Controls::AspectRatio3D() ); - myFunctorPtr = myNumericalFunctorPtr; -} - -FunctorType AspectRatio3D_i::GetFunctorType() -{ - return SMESH::FT_AspectRatio3D; -} - - -/* - Class : Warping_i - Description : Functor for calculating warping -*/ -Warping_i::Warping_i() -{ - myNumericalFunctorPtr.reset( new Controls::Warping() ); - myFunctorPtr = myNumericalFunctorPtr; -} - -FunctorType Warping_i::GetFunctorType() -{ - return SMESH::FT_Warping; -} - - -/* - Class : Taper_i - Description : Functor for calculating taper -*/ -Taper_i::Taper_i() -{ - myNumericalFunctorPtr.reset( new Controls::Taper() ); - myFunctorPtr = myNumericalFunctorPtr; -} - -FunctorType Taper_i::GetFunctorType() -{ - return SMESH::FT_Taper; -} - -/* - Class : Skew_i - Description : Functor for calculating skew in degrees -*/ -Skew_i::Skew_i() -{ - myNumericalFunctorPtr.reset( new Controls::Skew() ); - myFunctorPtr = myNumericalFunctorPtr; -} - -FunctorType Skew_i::GetFunctorType() -{ - return SMESH::FT_Skew; -} - -/* - Class : Area_i - Description : Functor for calculating area -*/ -Area_i::Area_i() -{ - myNumericalFunctorPtr.reset( new Controls::Area() ); - myFunctorPtr = myNumericalFunctorPtr; -} - -FunctorType Area_i::GetFunctorType() -{ - return SMESH::FT_Area; -} - -/* - Class : Volume3D_i - Description : Functor for calculating volume of 3D element -*/ -Volume3D_i::Volume3D_i() -{ - myNumericalFunctorPtr.reset( new Controls::Volume() ); - myFunctorPtr = myNumericalFunctorPtr; -} - -FunctorType Volume3D_i::GetFunctorType() -{ - return SMESH::FT_Volume3D; -} - -/* - Class : MaxElementLength2D_i - Description : Functor for calculating maximum length of 2D element -*/ -MaxElementLength2D_i::MaxElementLength2D_i() -{ - myNumericalFunctorPtr.reset( new Controls::MaxElementLength2D() ); - myFunctorPtr = myNumericalFunctorPtr; -} - -FunctorType MaxElementLength2D_i::GetFunctorType() -{ - return SMESH::FT_MaxElementLength2D; -} - -/* - Class : MaxElementLength3D_i - Description : Functor for calculating maximum length of 3D element -*/ -MaxElementLength3D_i::MaxElementLength3D_i() -{ - myNumericalFunctorPtr.reset( new Controls::MaxElementLength3D() ); - myFunctorPtr = myNumericalFunctorPtr; -} - -FunctorType MaxElementLength3D_i::GetFunctorType() -{ - return SMESH::FT_MaxElementLength3D; -} - -/* - Class : Length_i - Description : Functor for calculating length off edge -*/ -Length_i::Length_i() -{ - myNumericalFunctorPtr.reset( new Controls::Length() ); - myFunctorPtr = myNumericalFunctorPtr; -} - -FunctorType Length_i::GetFunctorType() -{ - return SMESH::FT_Length; -} - -/* - Class : Length2D_i - Description : Functor for calculating length of edge -*/ -Length2D_i::Length2D_i() -{ - myNumericalFunctorPtr.reset( new Controls::Length2D() ); - myFunctorPtr = myNumericalFunctorPtr; -} - -FunctorType Length2D_i::GetFunctorType() -{ - return SMESH::FT_Length2D; -} - -SMESH::Length2D::Values* Length2D_i::GetValues() -{ - SMESH::Controls::Length2D::TValues aValues; - (dynamic_cast(myFunctorPtr.get()))->GetValues( aValues ); - - long i = 0, iEnd = aValues.size(); - - SMESH::Length2D::Values_var aResult = new SMESH::Length2D::Values(iEnd); - aResult->length(iEnd); - - SMESH::Controls::Length2D::TValues::const_iterator anIter; - for ( anIter = aValues.begin() ; anIter != aValues.end(); anIter++, i++ ) - { - const SMESH::Controls::Length2D::Value& aVal = *anIter; - SMESH::Length2D::Value &aValue = aResult[ i ]; - - aValue.myLength = aVal.myLength; - aValue.myPnt1 = aVal.myPntId[ 0 ]; - aValue.myPnt2 = aVal.myPntId[ 1 ]; - } - - return aResult._retn(); -} - - -/* - Class : Length3D_i - Description : Functor for calculating length of edge -*/ -Length3D_i::Length3D_i() -{ - myNumericalFunctorPtr.reset( new Controls::Length3D() ); - myFunctorPtr = myNumericalFunctorPtr; -} - -FunctorType Length3D_i::GetFunctorType() -{ - return SMESH::FT_Length3D; -} - -// SMESH::Length3D::Values* Length3D_i::GetValues() -// { -// SMESH::Controls::Length3D::TValues aValues; -// (dynamic_cast(myFunctorPtr.get()))->GetValues( aValues ); - -// long i = 0, iEnd = aValues.size(); - -// SMESH::Length3D::Values_var aResult = new SMESH::Length3D::Values(iEnd); -// aResult->length(iEnd); - -// SMESH::Controls::Length3D::TValues::const_iterator anIter; -// for ( anIter = aValues.begin() ; anIter != aValues.end(); anIter++, i++ ) -// { -// const SMESH::Controls::Length3D::Value& aVal = *anIter; -// SMESH::Length3D::Value &aValue = aResult[ i ]; - -// aValue.myLength = aVal.myLength; -// aValue.myPnt1 = aVal.myPntId[ 0 ]; -// aValue.myPnt2 = aVal.myPntId[ 1 ]; -// } - -// return aResult._retn(); -// } - -/* - Class : Deflection2D_i - Description : Functor for calculating distance between a face and geometry -*/ -Deflection2D_i::Deflection2D_i() -{ - myNumericalFunctorPtr.reset( new Controls::Deflection2D() ); - myFunctorPtr = myNumericalFunctorPtr; -} - -FunctorType Deflection2D_i::GetFunctorType() -{ - return SMESH::FT_Deflection2D; -} - -/* - Class : MultiConnection_i - Description : Functor for calculating number of faces conneted to the edge -*/ -MultiConnection_i::MultiConnection_i() -{ - myNumericalFunctorPtr.reset( new Controls::MultiConnection() ); - myFunctorPtr = myNumericalFunctorPtr; -} - -FunctorType MultiConnection_i::GetFunctorType() -{ - return SMESH::FT_MultiConnection; -} - -/* - Class : BallDiameter_i - Description : Functor returning diameter of a ball element -*/ -BallDiameter_i::BallDiameter_i() -{ - myNumericalFunctorPtr.reset( new Controls::BallDiameter() ); - myFunctorPtr = myNumericalFunctorPtr; -} - -FunctorType BallDiameter_i::GetFunctorType() -{ - return SMESH::FT_BallDiameter; -} - -/* - Class : NodeConnectivityNumber_i - Description : Functor returning diameter of a ball element -*/ -NodeConnectivityNumber_i::NodeConnectivityNumber_i() -{ - myNumericalFunctorPtr.reset( new Controls::NodeConnectivityNumber() ); - myFunctorPtr = myNumericalFunctorPtr; -} - -FunctorType NodeConnectivityNumber_i::GetFunctorType() -{ - return SMESH::FT_NodeConnectivityNumber; -} - -/* - Class : MultiConnection2D_i - Description : Functor for calculating number of faces conneted to the edge -*/ -MultiConnection2D_i::MultiConnection2D_i() -{ - myNumericalFunctorPtr.reset( new Controls::MultiConnection2D() ); - myFunctorPtr = myNumericalFunctorPtr; -} - -FunctorType MultiConnection2D_i::GetFunctorType() -{ - return SMESH::FT_MultiConnection2D; -} - -SMESH::MultiConnection2D::Values* MultiConnection2D_i::GetValues() -{ - SMESH::Controls::MultiConnection2D::MValues aValues; - (dynamic_cast(myFunctorPtr.get()))->GetValues( aValues ); - - long i = 0, iEnd = aValues.size(); - - SMESH::MultiConnection2D::Values_var aResult = new SMESH::MultiConnection2D::Values(iEnd); - aResult->length(iEnd); - - SMESH::Controls::MultiConnection2D::MValues::const_iterator anIter; - for ( anIter = aValues.begin() ; anIter != aValues.end(); anIter++, i++ ) - { - const SMESH::Controls::MultiConnection2D::Value& aVal = (*anIter).first; - SMESH::MultiConnection2D::Value &aValue = aResult[ i ]; - - aValue.myPnt1 = aVal.myPntId[ 0 ]; - aValue.myPnt2 = aVal.myPntId[ 1 ]; - aValue.myNbConnects = (*anIter).second; - } - - return aResult._retn(); -} - -/* - PREDICATES -*/ - - -/* - Class : Predicate_i - Description : Base class for all predicates -*/ -CORBA::Boolean Predicate_i::IsSatisfy( CORBA::Long theId ) -{ - return myPredicatePtr->IsSatisfy( theId ); -} - -CORBA::Long Predicate_i::NbSatisfying( SMESH::SMESH_IDSource_ptr obj ) -{ - SMESH::SMESH_Mesh_var meshVar = obj->GetMesh(); - const SMDS_Mesh* meshDS = MeshPtr2SMDSMesh( meshVar ); - if ( !meshDS ) - return 0; - myPredicatePtr->SetMesh( meshDS ); - - SMDSAbs_ElementType elemType = SMDSAbs_ElementType( GetElementType() ); - - int nb = 0; - SMDS_ElemIteratorPtr elemIt = - SMESH::DownCast( meshVar )->GetElements( obj, GetElementType() ); - if ( elemIt ) - while ( elemIt->more() ) - { - const SMDS_MeshElement* e = elemIt->next(); - if ( e && e->GetType() == elemType ) - nb += myPredicatePtr->IsSatisfy( e->GetID() ); - } - return nb; -} - -Controls::PredicatePtr Predicate_i::GetPredicate() -{ - return myPredicatePtr; -} - -/* - Class : BadOrientedVolume_i - Description : Verify whether a mesh volume is incorrectly oriented from - the point of view of MED convention -*/ -BadOrientedVolume_i::BadOrientedVolume_i() -{ - Controls::PredicatePtr control( new Controls::BadOrientedVolume() ); - myFunctorPtr = myPredicatePtr = control; -} - -FunctorType BadOrientedVolume_i::GetFunctorType() -{ - return SMESH::FT_BadOrientedVolume; -} - -/* - Class : BareBorderVolume_i - Description : Verify whether a mesh volume has a free facet without a face on it -*/ -BareBorderVolume_i::BareBorderVolume_i() -{ - Controls::PredicatePtr control( new Controls::BareBorderVolume() ); - myFunctorPtr = myPredicatePtr = control; -} - -FunctorType BareBorderVolume_i::GetFunctorType() -{ - return SMESH::FT_BareBorderVolume; -} - -/* - Class : BareBorderFace_i - Description : Verify whether a mesh face has a free border without an edge on it -*/ -BareBorderFace_i::BareBorderFace_i() -{ - Controls::PredicatePtr control( new Controls::BareBorderFace() ); - myFunctorPtr = myPredicatePtr = control; -} - -FunctorType BareBorderFace_i::GetFunctorType() -{ - return SMESH::FT_BareBorderFace; -} - -/* - Class : OverConstrainedVolume_i - Description : Verify whether a mesh volume has only one facet shared with other volumes -*/ -OverConstrainedVolume_i::OverConstrainedVolume_i() -{ - Controls::PredicatePtr control( new Controls::OverConstrainedVolume() ); - myFunctorPtr = myPredicatePtr = control; -} - -FunctorType OverConstrainedVolume_i::GetFunctorType() -{ - return SMESH::FT_OverConstrainedVolume; -} - -/* - Class : OverConstrainedFace_i - Description : Verify whether a mesh face has only one border shared with other faces -*/ -OverConstrainedFace_i::OverConstrainedFace_i() -{ - Controls::PredicatePtr control( new Controls::OverConstrainedFace() ); - myFunctorPtr = myPredicatePtr = control; -} - -FunctorType OverConstrainedFace_i::GetFunctorType() -{ - return SMESH::FT_OverConstrainedFace; -} - -/* - Class : BelongToMeshGroup_i - Description : Verify whether a mesh element is included into a mesh group -*/ -BelongToMeshGroup_i::BelongToMeshGroup_i() -{ - myBelongToMeshGroup = Controls::BelongToMeshGroupPtr( new Controls::BelongToMeshGroup() ); - myFunctorPtr = myPredicatePtr = myBelongToMeshGroup; -} - -BelongToMeshGroup_i::~BelongToMeshGroup_i() -{ - SetGroup( SMESH::SMESH_GroupBase::_nil() ); -} - -void BelongToMeshGroup_i::SetGroup( SMESH::SMESH_GroupBase_ptr theGroup ) -{ - if ( myGroup->_is_equivalent( theGroup )) - return; - - if ( ! myGroup->_is_nil() ) - myGroup->UnRegister(); - - myGroup = SMESH_GroupBase::_duplicate( theGroup ); - - myBelongToMeshGroup->SetGroup( 0 ); - if ( SMESH_GroupBase_i* gr_i = SMESH::DownCast< SMESH_GroupBase_i* >( myGroup )) - { - myBelongToMeshGroup->SetGroup( gr_i->GetGroupDS() ); - myGroup->Register(); - } -} - -void BelongToMeshGroup_i::SetGroupID( const char* theID ) // IOR or StoreName -{ - myID = theID; - if ( strncmp( "IOR:", myID.c_str(), 4 ) == 0 ) // transient mode, no GUI - { - CORBA::Object_var obj = SMESH_Gen_i::GetORB()->string_to_object( myID.c_str() ); - SetGroup( SMESH::SMESH_GroupBase::_narrow( obj )); - } - else if ( strncmp( "0:", myID.c_str(), 2 ) == 0 ) // transient mode + GUI - { - SALOMEDS::SObject_wrap aSObj = SMESH_Gen_i::GetSMESHGen()->getStudyServant()->FindObjectID( myID.c_str() ); - if ( !aSObj->_is_nil() ) { - CORBA::Object_var obj = aSObj->GetObject(); - SetGroup( SMESH::SMESH_GroupBase::_narrow( obj )); - } - } - else if ( !myID.empty() ) // persistent mode - { - myBelongToMeshGroup->SetStoreName( myID ); - } -} - -std::string BelongToMeshGroup_i::GetGroupID() -{ - if ( myGroup->_is_nil() ) - SMESH::SMESH_GroupBase_var( GetGroup() ); // decref the returned pointer - - if ( !myGroup->_is_nil() ) - myID = SMESH_Gen_i::GetORB()->object_to_string( myGroup ); - - return myID; -} - -SMESH::SMESH_GroupBase_ptr BelongToMeshGroup_i::GetGroup() -{ - if ( myGroup->_is_nil() && myBelongToMeshGroup->GetGroup() ) - { - // search for a group in a current study - SMESH_Gen_i* aSMESHGen = SMESH_Gen_i::GetSMESHGen(); - if ( StudyContext* sc = aSMESHGen->GetStudyContext() ) - { - int id = 1; - std::string ior; - while (true) - { - ior = sc->getIORbyId( id++ ); - if ( ior.empty() ) break; - CORBA::Object_var obj = aSMESHGen->GetORB()->string_to_object( ior.c_str() ); - if ( SMESH_GroupBase_i* g_i = SMESH::DownCast( obj )) - if ( g_i->GetGroupDS() == myBelongToMeshGroup->GetGroup() ) - { - SetGroup( g_i->_this() ); - break; - } - } - } - } - return SMESH::SMESH_GroupBase::_duplicate( myGroup ); -} - -FunctorType BelongToMeshGroup_i::GetFunctorType() -{ - return SMESH::FT_BelongToMeshGroup; -} - -/* - Class : BelongToGeom_i - Description : Predicate for selection on geometrical support -*/ -BelongToGeom_i::BelongToGeom_i() -{ - myBelongToGeomPtr.reset( new Controls::BelongToGeom() ); - myFunctorPtr = myPredicatePtr = myBelongToGeomPtr; - myShapeName = 0; - myShapeID = 0; -} - -BelongToGeom_i::~BelongToGeom_i() -{ - CORBA::string_free( myShapeName ); - CORBA::string_free( myShapeID ); -} - -void BelongToGeom_i::SetGeom( GEOM::GEOM_Object_ptr theGeom ) -{ - if ( theGeom->_is_nil() ) - return; - TopoDS_Shape aLocShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( theGeom ); - myBelongToGeomPtr->SetGeom( aLocShape ); - TPythonDump()<SetGeom( theShape ); -} - -void BelongToGeom_i::SetElementType(ElementType theType) -{ - myBelongToGeomPtr->SetType(SMDSAbs_ElementType(theType)); - TPythonDump()<SetGeom( getShapeByName( myShapeName ) ); - TPythonDump()<SetGeom( S ); -} - -char* BelongToGeom_i::GetShapeName() -{ - return CORBA::string_dup( myShapeName ); -} - -char* BelongToGeom_i::GetShapeID() -{ - return CORBA::string_dup( myShapeID ); -} - -void BelongToGeom_i::SetTolerance( CORBA::Double theToler ) -{ - myBelongToGeomPtr->SetTolerance( theToler ); - TPythonDump()<GetTolerance(); -} - -/* - Class : BelongToSurface_i - Description : Predicate for selection on geometrical support -*/ -BelongToSurface_i::BelongToSurface_i( const Handle(Standard_Type)& theSurfaceType ) -{ - myElementsOnSurfacePtr.reset( new Controls::ElementsOnSurface() ); - myFunctorPtr = myPredicatePtr = myElementsOnSurfacePtr; - myShapeName = 0; - myShapeID = 0; - mySurfaceType = theSurfaceType; -} - -BelongToSurface_i::~BelongToSurface_i() -{ - CORBA::string_free( myShapeName ); - CORBA::string_free( myShapeID ); -} - -void BelongToSurface_i::SetSurface( GEOM::GEOM_Object_ptr theGeom, ElementType theType ) -{ - if ( theGeom->_is_nil() ) - return; - TopoDS_Shape aLocShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( theGeom ); - - if ( aLocShape.ShapeType() == TopAbs_FACE ) - { - Handle(Geom_Surface) aSurf = BRep_Tool::Surface( TopoDS::Face( aLocShape ) ); - if ( !aSurf.IsNull() && aSurf->DynamicType() == mySurfaceType ) - { - myElementsOnSurfacePtr->SetSurface( aLocShape, (SMDSAbs_ElementType)theType ); - return; - } - } - - myElementsOnSurfacePtr->SetSurface( TopoDS_Shape(), (SMDSAbs_ElementType)theType ); -} - -void BelongToSurface_i::SetShapeName( const char* theName, ElementType theType ) -{ - CORBA::string_free( myShapeName ); - myShapeName = CORBA::string_dup( theName ); - myElementsOnSurfacePtr->SetSurface( getShapeByName( myShapeName ), (SMDSAbs_ElementType)theType ); - TPythonDump()<SetSurface( S, (SMDSAbs_ElementType)theType ); -} - -char* BelongToSurface_i::GetShapeName() -{ - return CORBA::string_dup( myShapeName ); -} - -char* BelongToSurface_i::GetShapeID() -{ - return CORBA::string_dup( myShapeID ); -} - -void BelongToSurface_i::SetTolerance( CORBA::Double theToler ) -{ - myElementsOnSurfacePtr->SetTolerance( theToler ); - TPythonDump()<GetTolerance(); -} - -void BelongToSurface_i::SetUseBoundaries( CORBA::Boolean theUseBndRestrictions ) -{ - myElementsOnSurfacePtr->SetUseBoundaries( theUseBndRestrictions ); - TPythonDump()<GetUseBoundaries(); -} - - -/* - Class : BelongToPlane_i - Description : Verify whether mesh element lie in pointed Geom planar object -*/ - -BelongToPlane_i::BelongToPlane_i() -: BelongToSurface_i( STANDARD_TYPE( Geom_Plane ) ) -{ -} - -void BelongToPlane_i::SetPlane( GEOM::GEOM_Object_ptr theGeom, ElementType theType ) -{ - BelongToSurface_i::SetSurface( theGeom, theType ); - TPythonDump()<_is_nil() ) - return; - TopoDS_Shape aLocShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( theGeom ); - if ( !aLocShape.IsNull() && aLocShape.ShapeType() != TopAbs_FACE ) - aLocShape.Nullify(); - - BelongToSurface_i::myElementsOnSurfacePtr->SetSurface( aLocShape, (SMDSAbs_ElementType)theType ); - TPythonDump()<_is_nil() ) - return; - TopoDS_Shape aLocShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( theGeom ); - myLyingOnGeomPtr->SetGeom( aLocShape ); - TPythonDump()<SetGeom( theShape ); -} - -void LyingOnGeom_i::SetElementType(ElementType theType){ - myLyingOnGeomPtr->SetType(SMDSAbs_ElementType(theType)); - TPythonDump()<SetGeom( getShapeByName( myShapeName ) ); - TPythonDump()<SetGeom( S ); -} - -char* LyingOnGeom_i::GetShapeName() -{ - return CORBA::string_dup( myShapeName ); -} - -char* LyingOnGeom_i::GetShapeID() -{ - return CORBA::string_dup( myShapeID ); -} - -void LyingOnGeom_i::SetTolerance( CORBA::Double theToler ) -{ - myLyingOnGeomPtr->SetTolerance( theToler ); - TPythonDump()<GetTolerance(); -} - -/* - Class : FreeBorders_i - Description : Predicate for free borders -*/ -FreeBorders_i::FreeBorders_i() -{ - myPredicatePtr.reset(new Controls::FreeBorders()); - myFunctorPtr = myPredicatePtr; -} - -FunctorType FreeBorders_i::GetFunctorType() -{ - return SMESH::FT_FreeBorders; -} - -/* - Class : FreeEdges_i - Description : Predicate for free borders -*/ -FreeEdges_i::FreeEdges_i() -: myFreeEdgesPtr( new Controls::FreeEdges() ) -{ - myFunctorPtr = myPredicatePtr = myFreeEdgesPtr; -} - -SMESH::FreeEdges::Borders* FreeEdges_i::GetBorders() -{ - SMESH::Controls::FreeEdges::TBorders aBorders; - myFreeEdgesPtr->GetBoreders( aBorders ); - - long i = 0, iEnd = aBorders.size(); - - SMESH::FreeEdges::Borders_var aResult = new SMESH::FreeEdges::Borders; - aResult->length(iEnd); - - SMESH::Controls::FreeEdges::TBorders::const_iterator anIter; - for ( anIter = aBorders.begin() ; anIter != aBorders.end(); anIter++, i++ ) - { - const SMESH::Controls::FreeEdges::Border& aBord = *anIter; - SMESH::FreeEdges::Border &aBorder = aResult[ i ]; - - aBorder.myElemId = aBord.myElemId; - aBorder.myPnt1 = aBord.myPntId[ 0 ]; - aBorder.myPnt2 = aBord.myPntId[ 1 ]; - } - return aResult._retn(); -} - -FunctorType FreeEdges_i::GetFunctorType() -{ - return SMESH::FT_FreeEdges; -} - -/* - Class : FreeFaces_i - Description : Predicate for free faces -*/ -FreeFaces_i::FreeFaces_i() -{ - myPredicatePtr.reset(new Controls::FreeFaces()); - myFunctorPtr = myPredicatePtr; -} - -FunctorType FreeFaces_i::GetFunctorType() -{ - return SMESH::FT_FreeFaces; -} - -/* - Class : FreeNodes_i - Description : Predicate for free nodes -*/ -FreeNodes_i::FreeNodes_i() -{ - myPredicatePtr.reset(new Controls::FreeNodes()); - myFunctorPtr = myPredicatePtr; -} - -FunctorType FreeNodes_i::GetFunctorType() -{ - return SMESH::FT_FreeNodes; -} - -/* - Class : EqualNodes_i - Description : Predicate for Equal nodes -*/ -EqualNodes_i::EqualNodes_i() -{ - myCoincidentNodesPtr.reset(new Controls::CoincidentNodes()); - myFunctorPtr = myPredicatePtr = myCoincidentNodesPtr; -} - -FunctorType EqualNodes_i::GetFunctorType() -{ - return SMESH::FT_EqualNodes; -} - -void EqualNodes_i::SetTolerance( double tol ) -{ - myCoincidentNodesPtr->SetTolerance( tol ); -} - -double EqualNodes_i::GetTolerance() -{ - return myCoincidentNodesPtr->GetTolerance(); -} - -/* - Class : EqualEdges_i - Description : Predicate for Equal Edges -*/ -EqualEdges_i::EqualEdges_i() -{ - myPredicatePtr.reset(new Controls::CoincidentElements1D()); - myFunctorPtr = myPredicatePtr; -} - -FunctorType EqualEdges_i::GetFunctorType() -{ - return SMESH::FT_EqualEdges; -} - -/* - Class : EqualFaces_i - Description : Predicate for Equal Faces -*/ -EqualFaces_i::EqualFaces_i() -{ - myPredicatePtr.reset(new Controls::CoincidentElements2D()); - myFunctorPtr = myPredicatePtr; -} - -FunctorType EqualFaces_i::GetFunctorType() -{ - return SMESH::FT_EqualFaces; -} - -/* - Class : EqualVolumes_i - Description : Predicate for Equal Volumes -*/ -EqualVolumes_i::EqualVolumes_i() -{ - myPredicatePtr.reset(new Controls::CoincidentElements3D()); - myFunctorPtr = myPredicatePtr; -} - -FunctorType EqualVolumes_i::GetFunctorType() -{ - return SMESH::FT_EqualVolumes; -} - - -/* - Class : RangeOfIds_i - Description : Predicate for Range of Ids. - Range may be specified with two ways. - 1. Using AddToRange method - 2. With SetRangeStr method. Parameter of this method is a string - like as "1,2,3,50-60,63,67,70-" -*/ - -RangeOfIds_i::RangeOfIds_i() -{ - myRangeOfIdsPtr.reset( new Controls::RangeOfIds() ); - myFunctorPtr = myPredicatePtr = myRangeOfIdsPtr; -} - -void RangeOfIds_i::SetRange( const SMESH::smIdType_array& theIds ) -{ - SMESH::smIdType iEnd = theIds.length(); - for ( SMESH::smIdType i = 0; i < iEnd; i++ ) - myRangeOfIdsPtr->AddToRange( theIds[ i ] ); - TPythonDump()<SetRangeStr( - TCollection_AsciiString( (Standard_CString)theRange ) ); -} - -char* RangeOfIds_i::GetRangeStr() -{ - TCollection_AsciiString aStr; - myRangeOfIdsPtr->GetRangeStr( aStr ); - return CORBA::string_dup( aStr.ToCString() ); -} - -void RangeOfIds_i::SetElementType( ElementType theType ) -{ - myRangeOfIdsPtr->SetType( SMDSAbs_ElementType( theType ) ); - TPythonDump()<SetType(SMDSAbs_ElementType(theType)); - TPythonDump()<SetColorStr( - TCollection_AsciiString( (Standard_CString)theColor ) ); - TPythonDump()<GetColorStr( aStr ); - return CORBA::string_dup( aStr.ToCString() ); -} - -void GroupColor_i::SetElementType(ElementType theType) -{ - myGroupColorPtr->SetType(SMDSAbs_ElementType(theType)); - TPythonDump()<SetType(SMDSAbs_ElementType(theType)); - TPythonDump()<SetGeomType(SMDSAbs_GeometryType(theType)); - TPythonDump()<GetGeomType(); -} - -FunctorType ElemGeomType_i::GetFunctorType() -{ - return SMESH::FT_ElemGeomType; -} - -/* - Class : ElemEntityType_i - Description : Predicate check is element has indicated entity type -*/ -ElemEntityType_i::ElemEntityType_i() -{ - myElemEntityTypePtr.reset(new Controls::ElemEntityType()); - myFunctorPtr = myPredicatePtr = myElemEntityTypePtr; -} - -void ElemEntityType_i::SetElementType(ElementType theType) -{ - myElemEntityTypePtr->SetType(SMDSAbs_ElementType(theType)); - TPythonDump()<SetElemEntityType(SMDSAbs_EntityType (theEntityType)); - TPythonDump()<GetElemEntityType(); -} - -FunctorType ElemEntityType_i::GetFunctorType() -{ - return SMESH::FT_EntityType; -} - -/* - Class : CoplanarFaces_i - Description : Returns true if a mesh face is a coplanar neighbour to a given one -*/ -CoplanarFaces_i::CoplanarFaces_i() -{ - myCoplanarFacesPtr.reset(new Controls::CoplanarFaces()); - myFunctorPtr = myPredicatePtr = myCoplanarFacesPtr; -} - -void CoplanarFaces_i::SetFace ( CORBA::Long theFaceID ) -{ - myCoplanarFacesPtr->SetFace(theFaceID); - TPythonDump()<SetTolerance(theToler); - TPythonDump()<GetFace(); -} - -char* CoplanarFaces_i::GetFaceAsString () const -{ - TCollection_AsciiString str(Standard_Integer(myCoplanarFacesPtr->GetFace())); - return CORBA::string_dup( str.ToCString() ); -} - -CORBA::Double CoplanarFaces_i::GetTolerance() const -{ - return myCoplanarFacesPtr->GetTolerance(); -} - -FunctorType CoplanarFaces_i::GetFunctorType() -{ - return SMESH::FT_CoplanarFaces; -} - -/* - * Class : ConnectedElements_i - * Description : Returns true if an element is connected via other elements to the element - * located at a given point. - */ -ConnectedElements_i::ConnectedElements_i() -{ - myConnectedElementsPtr.reset(new Controls::ConnectedElements()); - myFunctorPtr = myPredicatePtr = myConnectedElementsPtr; -} - -FunctorType ConnectedElements_i::GetFunctorType() -{ - return FT_ConnectedElements; -} - -void ConnectedElements_i::SetElementType( ElementType theType ) -{ - myConnectedElementsPtr->SetType( SMDSAbs_ElementType( theType )); - TPythonDump() << this << ".SetElementType( " << theType << " )"; -} - -void ConnectedElements_i::SetPoint( CORBA::Double x, CORBA::Double y, CORBA::Double z ) -{ - myConnectedElementsPtr->SetPoint( x,y,z ); - myVertexID.clear(); - TPythonDump() << this << ".SetPoint( " << x << ", " << y << ", " << z << " )"; -} - -void ConnectedElements_i::SetVertex( GEOM::GEOM_Object_ptr vertex ) -{ - TopoDS_Shape shape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( vertex ); - if ( shape.IsNull() ) - THROW_SALOME_CORBA_EXCEPTION( "ConnectedElements_i::SetVertex(): NULL Vertex", - SALOME::BAD_PARAM ); - - TopExp_Explorer v( shape, TopAbs_VERTEX ); - if ( !v.More() ) - THROW_SALOME_CORBA_EXCEPTION( "ConnectedElements_i::SetVertex(): empty vertex", - SALOME::BAD_PARAM ); - - gp_Pnt p = BRep_Tool::Pnt( TopoDS::Vertex( v.Current() )); - myConnectedElementsPtr->SetPoint( p.X(), p.Y(), p.Z() ); - // - CORBA::String_var id = vertex->GetStudyEntry(); - myVertexID = id.in(); - - TPythonDump() << this << ".SetVertex( " << vertex << " )"; -} - -void ConnectedElements_i::SetNode ( SMESH::smIdType nodeID ) -{ - if ( nodeID < 1 ) - THROW_SALOME_CORBA_EXCEPTION( "ConnectedElements_i::SetNode(): nodeID must be > 0", - SALOME::BAD_PARAM ); - - myConnectedElementsPtr->SetNode( nodeID ); - myVertexID.clear(); - TPythonDump() << this << ".SetNode( " << nodeID << " )"; -} - -/*! - * \brief This is a comfort method for Filter dialog - */ -void ConnectedElements_i::SetThreshold ( const char* threshold, - SMESH::ConnectedElements::ThresholdType type ) -{ - if ( !threshold ) - THROW_SALOME_CORBA_EXCEPTION( "ConnectedElements_i::SetThreshold(): NULL threshold", - SALOME::BAD_PARAM ); - switch ( type ) - { - case SMESH::ConnectedElements::POINT: // read 3 node coordinates /////////////////// - { - std::vector< double > xyz; - char* endptr; - do - { - // skip a separator - while ( *threshold && - *threshold != '+' && - *threshold != '-' && - !isdigit( *threshold )) - ++threshold; - if ( !*threshold ) - break; - // read a coordinate - xyz.push_back( strtod( threshold, &endptr )); - if ( threshold == endptr ) - { - xyz.resize( xyz.size() - 1 ); - break; - } - threshold = endptr; - } - while ( xyz.size() < 3 ); - - if ( xyz.size() < 3 ) - THROW_SALOME_CORBA_EXCEPTION - ( "ConnectedElements_i::SetThreshold(): invalid point coordinates", SALOME::BAD_PARAM ); - - SetPoint( xyz[0], xyz[1], xyz[2] ); - break; - } - case SMESH::ConnectedElements::VERTEX: // get a VERTEX by its entry ///////////////// - { - SALOMEDS::SObject_wrap sobj = SMESH_Gen_i::GetSMESHGen()->getStudyServant()->FindObjectID( threshold ); - if ( sobj->_is_nil() ) - THROW_SALOME_CORBA_EXCEPTION - ( "ConnectedElements_i::SetThreshold(): invalid vertex study entry", SALOME::BAD_PARAM ); - CORBA::Object_var obj = sobj->GetObject(); - GEOM::GEOM_Object_var vertex = GEOM::GEOM_Object::_narrow( obj ); - if ( vertex->_is_nil() ) - THROW_SALOME_CORBA_EXCEPTION - ( "ConnectedElements_i::SetThreshold(): no GEOM_Object in SObject", SALOME::BAD_PARAM ); - SetVertex( vertex ); - break; - } - case SMESH::ConnectedElements::NODE: // read a node ID //////////////////////////// - { - char* endptr; - int id = strtol( threshold, &endptr, 10 ); - if ( threshold == endptr ) - THROW_SALOME_CORBA_EXCEPTION - ( "ConnectedElements_i::SetThreshold(): invalid node ID", SALOME::BAD_PARAM ); - SetNode( id ); - break; - } - default: - THROW_SALOME_CORBA_EXCEPTION - ( "ConnectedElements_i::SetThreshold(): invalid ThresholdType", SALOME::BAD_PARAM ); - } -} - -char* ConnectedElements_i::GetThreshold ( SMESH::ConnectedElements::ThresholdType& type ) -{ - std::string threshold; - if ( !myVertexID.empty() ) - { - threshold = myVertexID; - type = SMESH::ConnectedElements::VERTEX; - } - else - { - std::vector xyz = myConnectedElementsPtr->GetPoint(); - if ( xyz.size() == 3 ) - { - threshold = SMESH_Comment( xyz[0] ) << "; " << xyz[1] << "; " << xyz[2]; - type = SMESH::ConnectedElements::POINT; - } - else - { - threshold = SMESH_Comment( myConnectedElementsPtr->GetNode() ); - type = SMESH::ConnectedElements::NODE; - } - } - return CORBA::string_dup( threshold.c_str() ); -} - -/* - Class : Comparator_i - Description : Base class for comparators -*/ -Comparator_i::Comparator_i(): - myNumericalFunctor( NULL ) -{} - -Comparator_i::~Comparator_i() -{ - if ( myNumericalFunctor ) - myNumericalFunctor->UnRegister(); -} - -void Comparator_i::SetMargin( CORBA::Double theValue ) -{ - myComparatorPtr->SetMargin( theValue ); - TPythonDump()<GetMargin(); -} - -void Comparator_i::SetNumFunctor( NumericalFunctor_ptr theFunct ) -{ - if ( myNumericalFunctor ) - myNumericalFunctor->UnRegister(); - - myNumericalFunctor = DownCast(theFunct); - - if ( myNumericalFunctor ) - { - myComparatorPtr->SetNumFunctor( myNumericalFunctor->GetNumericalFunctor() ); - myNumericalFunctor->Register(); - TPythonDump()<" -*/ -MoreThan_i::MoreThan_i() -{ - myComparatorPtr.reset( new Controls::MoreThan() ); - myFunctorPtr = myPredicatePtr = myComparatorPtr; -} - -FunctorType MoreThan_i::GetFunctorType() -{ - return SMESH::FT_MoreThan; -} - - -/* - Class : EqualTo_i - Description : Comparator "=" -*/ -EqualTo_i::EqualTo_i() -: myEqualToPtr( new Controls::EqualTo() ) -{ - myFunctorPtr = myPredicatePtr = myComparatorPtr = myEqualToPtr; -} - -void EqualTo_i::SetTolerance( CORBA::Double theToler ) -{ - myEqualToPtr->SetTolerance( theToler ); - TPythonDump()<GetTolerance(); -} - -FunctorType EqualTo_i::GetFunctorType() -{ - return SMESH::FT_EqualTo; -} - -/* - Class : LogicalNOT_i - Description : Logical NOT predicate -*/ -LogicalNOT_i::LogicalNOT_i(): - myLogicalNOTPtr( new Controls::LogicalNOT() ), - myPredicate( NULL ) -{ - myFunctorPtr = myPredicatePtr = myLogicalNOTPtr; -} - -LogicalNOT_i::~LogicalNOT_i() -{ - if ( myPredicate ) - myPredicate->UnRegister(); -} - -void LogicalNOT_i::SetPredicate( Predicate_ptr thePredicate ) -{ - if ( myPredicate ) - myPredicate->UnRegister(); - - myPredicate = SMESH::GetPredicate(thePredicate); - - if ( myPredicate ){ - myLogicalNOTPtr->SetPredicate(myPredicate->GetPredicate()); - myPredicate->Register(); - TPythonDump()<UnRegister(); - - if ( myPredicate2 ) - myPredicate2->UnRegister(); -} - -void LogicalBinary_i::SetMesh( SMESH_Mesh_ptr theMesh ) -{ - if ( myPredicate1 ) - myPredicate1->SetMesh( theMesh ); - - if ( myPredicate2 ) - myPredicate2->SetMesh( theMesh ); -} - -void LogicalBinary_i::SetPredicate1( Predicate_ptr thePredicate ) -{ - if ( myPredicate1 ) - myPredicate1->UnRegister(); - - myPredicate1 = SMESH::GetPredicate(thePredicate); - - if ( myPredicate1 ){ - myLogicalBinaryPtr->SetPredicate1(myPredicate1->GetPredicate()); - myPredicate1->Register(); - TPythonDump()<UnRegister(); - - myPredicate2 = SMESH::GetPredicate(thePredicate); - - if ( myPredicate2 ){ - myLogicalBinaryPtr->SetPredicate2(myPredicate2->GetPredicate()); - myPredicate2->Register(); - TPythonDump()<activate_object( this ); -} - - -FilterManager_i::~FilterManager_i() -{ - //TPythonDump()<_this(); - TPythonDump()<_this(); - TPythonDump()<_this(); - TPythonDump()<_this(); - TPythonDump()<_this(); - TPythonDump()<_this(); - TPythonDump()<_this(); - TPythonDump()<_this(); - TPythonDump()<_this(); - TPythonDump()<_this(); - TPythonDump()<_this(); - TPythonDump()<_this(); - TPythonDump()<_this(); - TPythonDump()<_this(); - TPythonDump()<_this(); - TPythonDump()<_this(); - TPythonDump()<_this(); - TPythonDump()<_this(); - TPythonDump()<_this(); - TPythonDump()<_this(); - TPythonDump()<_this(); - TPythonDump()<_this(); - TPythonDump()<_this(); - TPythonDump()<_this(); - TPythonDump()<_this(); - TPythonDump()<_this(); - TPythonDump()<_this(); - TPythonDump()<_this(); - TPythonDump()<_this(); - TPythonDump()<_this(); - TPythonDump()<_this(); - TPythonDump()<_this(); - TPythonDump()<_this(); - TPythonDump()<_this(); - TPythonDump()<_this(); - TPythonDump()<_this(); - TPythonDump()<_this(); - TPythonDump()<_this(); - TPythonDump()<_this(); - TPythonDump()<_this(); - TPythonDump()<_this(); - TPythonDump()<_this(); - TPythonDump()<_this(); - TPythonDump()<_this(); - TPythonDump()<_this(); - TPythonDump()<_this(); - TPythonDump()<_this(); - TPythonDump()<_this(); - TPythonDump()<_this(); - TPythonDump()<_this(); - TPythonDump()<_this(); - TPythonDump()<_this(); - TPythonDump()<_this(); - TPythonDump()<UnRegister(); - - if(!CORBA::is_nil(myMesh)) - myMesh->UnRegister(); - - myPredicate = 0; - FindBaseObjects(); -} - -//======================================================================= -// name : Filter_i::SetPredicate -// Purpose : Set predicate -//======================================================================= -void Filter_i::SetPredicate( Predicate_ptr thePredicate ) -{ - if ( myPredicate ) - myPredicate->UnRegister(); - - myPredicate = SMESH::GetPredicate(thePredicate); - - if ( myPredicate ) +namespace SMESH { + /* + Class : Functor_i + Description : An abstract class for all functors + */ + Functor_i::Functor_i(): + SALOME::GenericObj_i( SMESH_Gen_i::GetPOA() ) { - myFilter.SetPredicate( myPredicate->GetPredicate() ); - myPredicate->Register(); - if ( const SMDS_Mesh* aMesh = MeshPtr2SMDSMesh(myMesh)) - myPredicate->GetPredicate()->SetMesh( aMesh ); - TPythonDump()<activate_object( this ); } - NotifyerAndWaiter::Modified(); -} -//======================================================================= -// name : Filter_i::GetElementType -// Purpose : Get entity type -//======================================================================= -SMESH::ElementType Filter_i::GetElementType() -{ - return myPredicate != 0 ? myPredicate->GetElementType() : SMESH::ALL; -} - -//======================================================================= -// name : Filter_i::SetMesh -// Purpose : Set mesh -//======================================================================= -void -Filter_i:: -SetMesh( SMESH_Mesh_ptr theMesh ) -{ - if(!CORBA::is_nil(theMesh)) - theMesh->Register(); - - if(!CORBA::is_nil(myMesh)) - myMesh->UnRegister(); - - myMesh = SMESH_Mesh::_duplicate( theMesh ); - TPythonDump()<GetPredicate()->SetMesh( aMesh ); -} - -SMESH::smIdType_array* -Filter_i:: -GetIDs() -{ - return GetElementsId(myMesh); -} - -//======================================================================= -// name : Filter_i::GetElementsId -// Purpose : Get ids of entities -//======================================================================= -void -Filter_i:: -GetElementsId( Predicate_i* thePredicate, - const SMDS_Mesh* theMesh, - Controls::Filter::TIdSequence& theSequence ) -{ - if (thePredicate) - Controls::Filter::GetElementsId(theMesh,thePredicate->GetPredicate(),theSequence); -} - -void -Filter_i:: -GetElementsId( Predicate_i* thePredicate, - SMESH_Mesh_ptr theMesh, - Controls::Filter::TIdSequence& theSequence ) -{ - if (thePredicate) - if(const SMDS_Mesh* aMesh = MeshPtr2SMDSMesh(theMesh)) - Controls::Filter::GetElementsId(aMesh,thePredicate->GetPredicate(),theSequence); -} - -SMESH::smIdType_array* -Filter_i:: -GetElementsId( SMESH_Mesh_ptr theMesh ) -{ - SMESH::smIdType_array_var anArray = new SMESH::smIdType_array; - if(!CORBA::is_nil(theMesh) && myPredicate){ - theMesh->Load(); - Controls::Filter::TIdSequence aSequence; - GetElementsId(myPredicate,theMesh,aSequence); - long i = 0, iEnd = aSequence.size(); - anArray->length( iEnd ); - for ( ; i < iEnd; i++ ) - anArray[ i ] = aSequence[i]; - } - return anArray._retn(); -} - -SMESH::smIdType_array* -Filter_i:: -GetElementsIdFromParts( const ListOfIDSources& theParts ) -{ - SMESH::smIdType_array_var array = new SMESH::smIdType_array; - if ( theParts.length() > 0 && myPredicate ) + Functor_i::~Functor_i() { - SMESH_Mesh_ptr mesh = theParts[0]->GetMesh(); - mesh->Load(); - const SMDS_Mesh* meshDS = MeshPtr2SMDSMesh( mesh ); - Controls::Filter::TIdSequence totalSequence; - for ( CORBA::ULong i = 0; i < theParts.length(); ++i ) + //TPythonDump()<SetMesh( MeshPtr2SMDSMesh( theMesh ) ); + TPythonDump()<GetType(); + } + + + /* + Class : NumericalFunctor_i + Description : Base class for numerical functors + */ + CORBA::Double NumericalFunctor_i::GetValue( SMESH::smIdType theId ) + { + return myNumericalFunctorPtr->GetValue( theId ); + } + + CORBA::Boolean NumericalFunctor_i::IsApplicable( SMESH::smIdType theElementId ) + { + return myNumericalFunctorPtr->IsApplicable( theElementId ); + } + + SMESH::Histogram* NumericalFunctor_i::GetHistogram(CORBA::Short nbIntervals, CORBA::Boolean isLogarithmic) + { + std::vector nbEvents; + std::vector funValues; + std::vector<::smIdType> elements; + myNumericalFunctorPtr->GetHistogram(nbIntervals, nbEvents, funValues ,elements, 0, isLogarithmic); + + SMESH::Histogram_var histogram = new SMESH::Histogram; + + nbIntervals = CORBA::Short( Min( int( nbEvents.size()), + int( funValues.size() - 1 ))); + if ( nbIntervals > 0 ) { - if ( SMESH::Filter_i* filter = SMESH::DownCast( theParts[i] )) - filter->SetMesh( mesh ); - SMDS_ElemIteratorPtr iter = SMESH_Mesh_i::GetElements( theParts[i], GetElementType() ); - if ( iter && meshDS ) + histogram->length( nbIntervals ); + for ( int i = 0; i < nbIntervals; ++i ) { - Controls::Filter::TIdSequence sequence; - Controls::Filter::GetElementsId( meshDS, myPredicate->GetPredicate(), sequence, iter ); - totalSequence.insert( totalSequence.end(), sequence.begin(), sequence.end() ); + HistogramRectangle& rect = histogram[i]; + rect.nbEvents = nbEvents[i]; + rect.min = funValues[i]; + rect.max = funValues[i+1]; } } - array->length( totalSequence.size() ); - for ( size_t i = 0; i < totalSequence.size(); ++i ) - array[ i ] = totalSequence[ i ]; + return histogram._retn(); } - return array._retn(); -} -//============================================================================= -/*! - * \brief Returns number of mesh elements per each \a EntityType - */ -//============================================================================= - -SMESH::smIdType_array* ::Filter_i::GetMeshInfo() -{ - SMESH::smIdType_array_var aRes = new SMESH::smIdType_array(); - aRes->length(SMESH::Entity_Last); - for (int i = 0; i < SMESH::Entity_Last; i++) - aRes[i] = 0; - - if ( !CORBA::is_nil(myMesh) && myPredicate ) + SMESH::Histogram* NumericalFunctor_i::GetLocalHistogram(CORBA::Short nbIntervals, + CORBA::Boolean isLogarithmic, + SMESH::SMESH_IDSource_ptr object) { - const SMDS_Mesh* aMesh = MeshPtr2SMDSMesh(myMesh); - SMDS_ElemIteratorPtr it = aMesh->elementsIterator( SMDSAbs_ElementType( GetElementType() )); - while ( it->more() ) + SMESH::Histogram_var histogram = new SMESH::Histogram; + + std::vector nbEvents; + std::vector funValues; + std::vector<::smIdType> elements; + + SMDS_ElemIteratorPtr elemIt; + if ( SMESH::DownCast< SMESH_GroupOnFilter_i* >( object ) || + SMESH::DownCast< SMESH::Filter_i* >( object )) { - const SMDS_MeshElement* anElem = it->next(); - if ( myPredicate->IsSatisfy( anElem->GetID() ) ) - aRes[ anElem->GetEntityType() ]++; + elemIt = SMESH_Mesh_i::GetElements( object, GetElementType() ); + if ( !elemIt ) return histogram._retn(); } - } - - return aRes._retn(); -} - -//============================================================================= -/*! - * \brief Returns number of mesh elements of each \a ElementType - */ -//============================================================================= - -SMESH::smIdType_array* ::Filter_i::GetNbElementsByType() -{ - SMESH::smIdType_array_var aRes = new SMESH::smIdType_array(); - aRes->length(SMESH::NB_ELEMENT_TYPES); - for (int i = 0; i < SMESH::NB_ELEMENT_TYPES; i++) - aRes[i] = 0; - - if ( !CORBA::is_nil(myMesh) && myPredicate ) { - const SMDS_Mesh* aMesh = MeshPtr2SMDSMesh(myMesh); - SMDS_ElemIteratorPtr it = aMesh->elementsIterator( SMDSAbs_ElementType( GetElementType() )); - SMESH::smIdType& nbElems = aRes[ GetElementType() ]; - while ( it->more() ) + else { - const SMDS_MeshElement* anElem = it->next(); - if ( myPredicate->IsSatisfy( anElem->GetID() ) ) - nbElems++; + SMESH::SMESH_Mesh_var mesh = object->GetMesh(); + SMESH::smIdType_array_var objNbElems = object->GetNbElementsByType(); + SMESH::smIdType_array_var meshNbElems = mesh-> GetNbElementsByType(); + if ( meshNbElems[ GetElementType() ] != + objNbElems [ GetElementType() ] ) + { + elements.reserve( objNbElems[ GetElementType() ]); + elemIt = SMESH_Mesh_i::GetElements( object, GetElementType() ); + } + } + if ( elemIt ) + { + while ( elemIt->more() ) + elements.push_back( elemIt->next()->GetID() ); + if ( elements.empty() ) return histogram._retn(); + } + + myNumericalFunctorPtr->GetHistogram(nbIntervals,nbEvents,funValues, elements, 0, isLogarithmic); + + nbIntervals = CORBA::Short( Min( int( nbEvents.size()), + int( funValues.size() - 1 ))); + if ( nbIntervals > 0 ) + { + histogram->length( nbIntervals ); + for ( int i = 0; i < nbIntervals; ++i ) + { + HistogramRectangle& rect = histogram[i]; + rect.nbEvents = nbEvents[i]; + rect.min = funValues[i]; + rect.max = funValues[i+1]; + } + } + return histogram._retn(); + } + + void NumericalFunctor_i::SetPrecision( CORBA::Long thePrecision ) + { + myNumericalFunctorPtr->SetPrecision( thePrecision ); + TPythonDump()<GetPrecision(); + } + + Controls::NumericalFunctorPtr NumericalFunctor_i::GetNumericalFunctor() + { + return myNumericalFunctorPtr; + } + + + /* + Class : SMESH_MinimumAngle + Description : Functor for calculation of minimum angle + */ + MinimumAngle_i::MinimumAngle_i() + { + myNumericalFunctorPtr.reset( new Controls::MinimumAngle() ); + myFunctorPtr = myNumericalFunctorPtr; + } + + FunctorType MinimumAngle_i::GetFunctorType() + { + return SMESH::FT_MinimumAngle; + } + + + /* + Class : AspectRatio + Description : Functor for calculating aspect ratio + */ + AspectRatio_i::AspectRatio_i() + { + myNumericalFunctorPtr.reset( new Controls::AspectRatio() ); + myFunctorPtr = myNumericalFunctorPtr; + } + + FunctorType AspectRatio_i::GetFunctorType() + { + return SMESH::FT_AspectRatio; + } + + + /* + Class : AspectRatio3D + Description : Functor for calculating aspect ratio 3D + */ + AspectRatio3D_i::AspectRatio3D_i() + { + myNumericalFunctorPtr.reset( new Controls::AspectRatio3D() ); + myFunctorPtr = myNumericalFunctorPtr; + } + + FunctorType AspectRatio3D_i::GetFunctorType() + { + return SMESH::FT_AspectRatio3D; + } + + + /* + Class : Warping_i + Description : Functor for calculating warping + */ + Warping_i::Warping_i() + { + myNumericalFunctorPtr.reset( new Controls::Warping() ); + myFunctorPtr = myNumericalFunctorPtr; + } + + FunctorType Warping_i::GetFunctorType() + { + return SMESH::FT_Warping; + } + + + /* + Class : Taper_i + Description : Functor for calculating taper + */ + Taper_i::Taper_i() + { + myNumericalFunctorPtr.reset( new Controls::Taper() ); + myFunctorPtr = myNumericalFunctorPtr; + } + + FunctorType Taper_i::GetFunctorType() + { + return SMESH::FT_Taper; + } + + /* + Class : Skew_i + Description : Functor for calculating skew in degrees + */ + Skew_i::Skew_i() + { + myNumericalFunctorPtr.reset( new Controls::Skew() ); + myFunctorPtr = myNumericalFunctorPtr; + } + + FunctorType Skew_i::GetFunctorType() + { + return SMESH::FT_Skew; + } + + /* + Class : Area_i + Description : Functor for calculating area + */ + Area_i::Area_i() + { + myNumericalFunctorPtr.reset( new Controls::Area() ); + myFunctorPtr = myNumericalFunctorPtr; + } + + FunctorType Area_i::GetFunctorType() + { + return SMESH::FT_Area; + } + + /* + Class : Volume3D_i + Description : Functor for calculating volume of 3D element + */ + Volume3D_i::Volume3D_i() + { + myNumericalFunctorPtr.reset( new Controls::Volume() ); + myFunctorPtr = myNumericalFunctorPtr; + } + + FunctorType Volume3D_i::GetFunctorType() + { + return SMESH::FT_Volume3D; + } + + /* + Class : MaxElementLength2D_i + Description : Functor for calculating maximum length of 2D element + */ + MaxElementLength2D_i::MaxElementLength2D_i() + { + myNumericalFunctorPtr.reset( new Controls::MaxElementLength2D() ); + myFunctorPtr = myNumericalFunctorPtr; + } + + FunctorType MaxElementLength2D_i::GetFunctorType() + { + return SMESH::FT_MaxElementLength2D; + } + + /* + Class : MaxElementLength3D_i + Description : Functor for calculating maximum length of 3D element + */ + MaxElementLength3D_i::MaxElementLength3D_i() + { + myNumericalFunctorPtr.reset( new Controls::MaxElementLength3D() ); + myFunctorPtr = myNumericalFunctorPtr; + } + + FunctorType MaxElementLength3D_i::GetFunctorType() + { + return SMESH::FT_MaxElementLength3D; + } + + /* + Class : Length_i + Description : Functor for calculating length off edge + */ + Length_i::Length_i() + { + myNumericalFunctorPtr.reset( new Controls::Length() ); + myFunctorPtr = myNumericalFunctorPtr; + } + + FunctorType Length_i::GetFunctorType() + { + return SMESH::FT_Length; + } + + /* + Class : Length2D_i + Description : Functor for calculating length of edge + */ + Length2D_i::Length2D_i() + { + myNumericalFunctorPtr.reset( new Controls::Length2D() ); + myFunctorPtr = myNumericalFunctorPtr; + } + + FunctorType Length2D_i::GetFunctorType() + { + return SMESH::FT_Length2D; + } + + SMESH::Length2D::Values* Length2D_i::GetValues() + { + SMESH::Controls::Length2D::TValues aValues; + (dynamic_cast(myFunctorPtr.get()))->GetValues( aValues ); + + long i = 0, iEnd = aValues.size(); + + SMESH::Length2D::Values_var aResult = new SMESH::Length2D::Values(iEnd); + aResult->length(iEnd); + + SMESH::Controls::Length2D::TValues::const_iterator anIter; + for ( anIter = aValues.begin() ; anIter != aValues.end(); anIter++, i++ ) + { + const SMESH::Controls::Length2D::Value& aVal = *anIter; + SMESH::Length2D::Value &aValue = aResult[ i ]; + + aValue.myLength = aVal.myLength; + aValue.myPnt1 = aVal.myPntId[ 0 ]; + aValue.myPnt2 = aVal.myPntId[ 1 ]; + } + + return aResult._retn(); + } + + + /* + Class : Length3D_i + Description : Functor for calculating length of edge + */ + Length3D_i::Length3D_i() + { + myNumericalFunctorPtr.reset( new Controls::Length3D() ); + myFunctorPtr = myNumericalFunctorPtr; + } + + FunctorType Length3D_i::GetFunctorType() + { + return SMESH::FT_Length3D; + } + + // SMESH::Length3D::Values* Length3D_i::GetValues() + // { + // SMESH::Controls::Length3D::TValues aValues; + // (dynamic_cast(myFunctorPtr.get()))->GetValues( aValues ); + + // long i = 0, iEnd = aValues.size(); + + // SMESH::Length3D::Values_var aResult = new SMESH::Length3D::Values(iEnd); + // aResult->length(iEnd); + + // SMESH::Controls::Length3D::TValues::const_iterator anIter; + // for ( anIter = aValues.begin() ; anIter != aValues.end(); anIter++, i++ ) + // { + // const SMESH::Controls::Length3D::Value& aVal = *anIter; + // SMESH::Length3D::Value &aValue = aResult[ i ]; + + // aValue.myLength = aVal.myLength; + // aValue.myPnt1 = aVal.myPntId[ 0 ]; + // aValue.myPnt2 = aVal.myPntId[ 1 ]; + // } + + // return aResult._retn(); + // } + + /* + Class : Deflection2D_i + Description : Functor for calculating distance between a face and geometry + */ + Deflection2D_i::Deflection2D_i() + { + myNumericalFunctorPtr.reset( new Controls::Deflection2D() ); + myFunctorPtr = myNumericalFunctorPtr; + } + + FunctorType Deflection2D_i::GetFunctorType() + { + return SMESH::FT_Deflection2D; + } + + /* + Class : MultiConnection_i + Description : Functor for calculating number of faces conneted to the edge + */ + MultiConnection_i::MultiConnection_i() + { + myNumericalFunctorPtr.reset( new Controls::MultiConnection() ); + myFunctorPtr = myNumericalFunctorPtr; + } + + FunctorType MultiConnection_i::GetFunctorType() + { + return SMESH::FT_MultiConnection; + } + + /* + Class : BallDiameter_i + Description : Functor returning diameter of a ball element + */ + BallDiameter_i::BallDiameter_i() + { + myNumericalFunctorPtr.reset( new Controls::BallDiameter() ); + myFunctorPtr = myNumericalFunctorPtr; + } + + FunctorType BallDiameter_i::GetFunctorType() + { + return SMESH::FT_BallDiameter; + } + + /* + Class : NodeConnectivityNumber_i + Description : Functor returning diameter of a ball element + */ + NodeConnectivityNumber_i::NodeConnectivityNumber_i() + { + myNumericalFunctorPtr.reset( new Controls::NodeConnectivityNumber() ); + myFunctorPtr = myNumericalFunctorPtr; + } + + FunctorType NodeConnectivityNumber_i::GetFunctorType() + { + return SMESH::FT_NodeConnectivityNumber; + } + + /* + Class : MultiConnection2D_i + Description : Functor for calculating number of faces conneted to the edge + */ + MultiConnection2D_i::MultiConnection2D_i() + { + myNumericalFunctorPtr.reset( new Controls::MultiConnection2D() ); + myFunctorPtr = myNumericalFunctorPtr; + } + + FunctorType MultiConnection2D_i::GetFunctorType() + { + return SMESH::FT_MultiConnection2D; + } + + SMESH::MultiConnection2D::Values* MultiConnection2D_i::GetValues() + { + SMESH::Controls::MultiConnection2D::MValues aValues; + (dynamic_cast(myFunctorPtr.get()))->GetValues( aValues ); + + long i = 0, iEnd = aValues.size(); + + SMESH::MultiConnection2D::Values_var aResult = new SMESH::MultiConnection2D::Values(iEnd); + aResult->length(iEnd); + + SMESH::Controls::MultiConnection2D::MValues::const_iterator anIter; + for ( anIter = aValues.begin() ; anIter != aValues.end(); anIter++, i++ ) + { + const SMESH::Controls::MultiConnection2D::Value& aVal = (*anIter).first; + SMESH::MultiConnection2D::Value &aValue = aResult[ i ]; + + aValue.myPnt1 = aVal.myPntId[ 0 ]; + aValue.myPnt2 = aVal.myPntId[ 1 ]; + aValue.myNbConnects = (*anIter).second; + } + + return aResult._retn(); + } + + /* + PREDICATES + */ + + + /* + Class : Predicate_i + Description : Base class for all predicates + */ + CORBA::Boolean Predicate_i::IsSatisfy( CORBA::Long theId ) + { + return myPredicatePtr->IsSatisfy( theId ); + } + + CORBA::Long Predicate_i::NbSatisfying( SMESH::SMESH_IDSource_ptr obj ) + { + SMESH::SMESH_Mesh_var meshVar = obj->GetMesh(); + const SMDS_Mesh* meshDS = MeshPtr2SMDSMesh( meshVar ); + if ( !meshDS ) + return 0; + myPredicatePtr->SetMesh( meshDS ); + + SMDSAbs_ElementType elemType = SMDSAbs_ElementType( GetElementType() ); + + int nb = 0; + SMDS_ElemIteratorPtr elemIt = + SMESH::DownCast( meshVar )->GetElements( obj, GetElementType() ); + if ( elemIt ) + while ( elemIt->more() ) + { + const SMDS_MeshElement* e = elemIt->next(); + if ( e && e->GetType() == elemType ) + nb += myPredicatePtr->IsSatisfy( e->GetID() ); + } + return nb; + } + + Controls::PredicatePtr Predicate_i::GetPredicate() + { + return myPredicatePtr; + } + + /* + Class : BadOrientedVolume_i + Description : Verify whether a mesh volume is incorrectly oriented from + the point of view of MED convention + */ + BadOrientedVolume_i::BadOrientedVolume_i() + { + Controls::PredicatePtr control( new Controls::BadOrientedVolume() ); + myFunctorPtr = myPredicatePtr = control; + } + + FunctorType BadOrientedVolume_i::GetFunctorType() + { + return SMESH::FT_BadOrientedVolume; + } + + /* + Class : BareBorderVolume_i + Description : Verify whether a mesh volume has a free facet without a face on it + */ + BareBorderVolume_i::BareBorderVolume_i() + { + Controls::PredicatePtr control( new Controls::BareBorderVolume() ); + myFunctorPtr = myPredicatePtr = control; + } + + FunctorType BareBorderVolume_i::GetFunctorType() + { + return SMESH::FT_BareBorderVolume; + } + + /* + Class : BareBorderFace_i + Description : Verify whether a mesh face has a free border without an edge on it + */ + BareBorderFace_i::BareBorderFace_i() + { + Controls::PredicatePtr control( new Controls::BareBorderFace() ); + myFunctorPtr = myPredicatePtr = control; + } + + FunctorType BareBorderFace_i::GetFunctorType() + { + return SMESH::FT_BareBorderFace; + } + + /* + Class : OverConstrainedVolume_i + Description : Verify whether a mesh volume has only one facet shared with other volumes + */ + OverConstrainedVolume_i::OverConstrainedVolume_i() + { + Controls::PredicatePtr control( new Controls::OverConstrainedVolume() ); + myFunctorPtr = myPredicatePtr = control; + } + + FunctorType OverConstrainedVolume_i::GetFunctorType() + { + return SMESH::FT_OverConstrainedVolume; + } + + /* + Class : OverConstrainedFace_i + Description : Verify whether a mesh face has only one border shared with other faces + */ + OverConstrainedFace_i::OverConstrainedFace_i() + { + Controls::PredicatePtr control( new Controls::OverConstrainedFace() ); + myFunctorPtr = myPredicatePtr = control; + } + + FunctorType OverConstrainedFace_i::GetFunctorType() + { + return SMESH::FT_OverConstrainedFace; + } + + /* + Class : BelongToMeshGroup_i + Description : Verify whether a mesh element is included into a mesh group + */ + BelongToMeshGroup_i::BelongToMeshGroup_i() + { + myBelongToMeshGroup = Controls::BelongToMeshGroupPtr( new Controls::BelongToMeshGroup() ); + myFunctorPtr = myPredicatePtr = myBelongToMeshGroup; + } + + BelongToMeshGroup_i::~BelongToMeshGroup_i() + { + SetGroup( SMESH::SMESH_GroupBase::_nil() ); + } + + void BelongToMeshGroup_i::SetGroup( SMESH::SMESH_GroupBase_ptr theGroup ) + { + if ( myGroup->_is_equivalent( theGroup )) + return; + + if ( ! myGroup->_is_nil() ) + myGroup->UnRegister(); + + myGroup = SMESH_GroupBase::_duplicate( theGroup ); + + myBelongToMeshGroup->SetGroup( 0 ); + if ( SMESH_GroupBase_i* gr_i = SMESH::DownCast< SMESH_GroupBase_i* >( myGroup )) + { + myBelongToMeshGroup->SetGroup( gr_i->GetGroupDS() ); + myGroup->Register(); } } - return aRes._retn(); -} - - -//================================================================================ -/*! - * \brief Return GetElementType() within an array - * Implement SMESH_IDSource interface - */ -//================================================================================ - -SMESH::array_of_ElementType* Filter_i::GetTypes() -{ - SMESH::array_of_ElementType_var types = new SMESH::array_of_ElementType; - - // check if any element passes through the filter - if ( !CORBA::is_nil(myMesh) && myPredicate ) + void BelongToMeshGroup_i::SetGroupID( const char* theID ) // IOR or StoreName { - const SMDS_Mesh* aMesh = MeshPtr2SMDSMesh(myMesh); - SMDS_ElemIteratorPtr it = aMesh->elementsIterator( SMDSAbs_ElementType( GetElementType() )); - bool satisfies = false; - while ( !satisfies && it->more() ) - satisfies = myPredicate->IsSatisfy( it->next()->GetID() ); - if ( satisfies ) { - types->length( 1 ); - types[0] = GetElementType(); + myID = theID; + if ( strncmp( "IOR:", myID.c_str(), 4 ) == 0 ) // transient mode, no GUI + { + CORBA::Object_var obj = SMESH_Gen_i::GetORB()->string_to_object( myID.c_str() ); + SetGroup( SMESH::SMESH_GroupBase::_narrow( obj )); + } + else if ( strncmp( "0:", myID.c_str(), 2 ) == 0 ) // transient mode + GUI + { + SALOMEDS::SObject_wrap aSObj = SMESH_Gen_i::GetSMESHGen()->getStudyServant()->FindObjectID( myID.c_str() ); + if ( !aSObj->_is_nil() ) { + CORBA::Object_var obj = aSObj->GetObject(); + SetGroup( SMESH::SMESH_GroupBase::_narrow( obj )); + } + } + else if ( !myID.empty() ) // persistent mode + { + myBelongToMeshGroup->SetStoreName( myID ); } } - return types._retn(); -} -//======================================================================= -//function : GetMesh -//purpose : Returns mesh -//======================================================================= - -SMESH::SMESH_Mesh_ptr Filter_i::GetMesh() -{ - return SMESH_Mesh::_duplicate( myMesh ); -} - -//======================================================================= -//function : GetVtkUgStream -//purpose : Return data vtk unstructured grid (not implemented) -//======================================================================= - -SALOMEDS::TMPFile* Filter_i::GetVtkUgStream() -{ - SALOMEDS::TMPFile_var SeqFile; - return SeqFile._retn(); -} -//======================================================================= -// name : getCriteria -// Purpose : Retrieve criterions from predicate -//======================================================================= -static inline void getPrediacates( Predicate_i* thePred, - std::vector & thePredVec ) -{ - const int aFType = thePred->GetFunctorType(); - - switch ( aFType ) + std::string BelongToMeshGroup_i::GetGroupID() { - case FT_LogicalNOT: - { - Predicate_i* aPred = ( dynamic_cast( thePred ) )->GetPredicate_i(); - getPrediacates( aPred, thePredVec ); - break; + if ( myGroup->_is_nil() ) + SMESH::SMESH_GroupBase_var( GetGroup() ); // decref the returned pointer + + if ( !myGroup->_is_nil() ) + myID = SMESH_Gen_i::GetORB()->object_to_string( myGroup ); + + return myID; } - case FT_LogicalAND: - case FT_LogicalOR: + + SMESH::SMESH_GroupBase_ptr BelongToMeshGroup_i::GetGroup() { - Predicate_i* aPred1 = ( dynamic_cast( thePred ) )->GetPredicate1_i(); - Predicate_i* aPred2 = ( dynamic_cast( thePred ) )->GetPredicate2_i(); - getPrediacates( aPred1, thePredVec ); - getPrediacates( aPred2, thePredVec ); - break; - } - default:; + if ( myGroup->_is_nil() && myBelongToMeshGroup->GetGroup() ) + { + // search for a group in a current study + SMESH_Gen_i* aSMESHGen = SMESH_Gen_i::GetSMESHGen(); + if ( StudyContext* sc = aSMESHGen->GetStudyContext() ) + { + int id = 1; + std::string ior; + while (true) + { + ior = sc->getIORbyId( id++ ); + if ( ior.empty() ) break; + CORBA::Object_var obj = aSMESHGen->GetORB()->string_to_object( ior.c_str() ); + if ( SMESH_GroupBase_i* g_i = SMESH::DownCast( obj )) + if ( g_i->GetGroupDS() == myBelongToMeshGroup->GetGroup() ) + { + SetGroup( g_i->_this() ); + break; + } + } + } + } + return SMESH::SMESH_GroupBase::_duplicate( myGroup ); } - thePredVec.push_back( thePred ); -} -//======================================================================= -// name : getCriteria -// Purpose : Retrieve criterions from predicate -//======================================================================= -static inline bool getCriteria( Predicate_i* thePred, - SMESH::Filter::Criteria_out theCriteria ) -{ - const int aFType = thePred->GetFunctorType(); - - switch ( aFType ) + FunctorType BelongToMeshGroup_i::GetFunctorType() { - case FT_LogicalNOT: + return SMESH::FT_BelongToMeshGroup; + } + + /* + Class : BelongToGeom_i + Description : Predicate for selection on geometrical support + */ + BelongToGeom_i::BelongToGeom_i() + { + myBelongToGeomPtr.reset( new Controls::BelongToGeom() ); + myFunctorPtr = myPredicatePtr = myBelongToGeomPtr; + myShapeName = 0; + myShapeID = 0; + } + + BelongToGeom_i::~BelongToGeom_i() + { + CORBA::string_free( myShapeName ); + CORBA::string_free( myShapeID ); + } + + void BelongToGeom_i::SetGeom( GEOM::GEOM_Object_ptr theGeom ) + { + if ( theGeom->_is_nil() ) + return; + TopoDS_Shape aLocShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( theGeom ); + myBelongToGeomPtr->SetGeom( aLocShape ); + TPythonDump()<SetGeom( theShape ); + } + + void BelongToGeom_i::SetElementType(ElementType theType) + { + myBelongToGeomPtr->SetType(SMDSAbs_ElementType(theType)); + TPythonDump()<SetGeom( getShapeByName( myShapeName ) ); + TPythonDump()<SetGeom( S ); + } + + char* BelongToGeom_i::GetShapeName() + { + return CORBA::string_dup( myShapeName ); + } + + char* BelongToGeom_i::GetShapeID() + { + return CORBA::string_dup( myShapeID ); + } + + void BelongToGeom_i::SetTolerance( CORBA::Double theToler ) + { + myBelongToGeomPtr->SetTolerance( theToler ); + TPythonDump()<GetTolerance(); + } + + /* + Class : BelongToSurface_i + Description : Predicate for selection on geometrical support + */ + BelongToSurface_i::BelongToSurface_i( const Handle(Standard_Type)& theSurfaceType ) + { + myElementsOnSurfacePtr.reset( new Controls::ElementsOnSurface() ); + myFunctorPtr = myPredicatePtr = myElementsOnSurfacePtr; + myShapeName = 0; + myShapeID = 0; + mySurfaceType = theSurfaceType; + } + + BelongToSurface_i::~BelongToSurface_i() + { + CORBA::string_free( myShapeName ); + CORBA::string_free( myShapeID ); + } + + void BelongToSurface_i::SetSurface( GEOM::GEOM_Object_ptr theGeom, ElementType theType ) + { + if ( theGeom->_is_nil() ) + return; + TopoDS_Shape aLocShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( theGeom ); + + if ( aLocShape.ShapeType() == TopAbs_FACE ) + { + Handle(Geom_Surface) aSurf = BRep_Tool::Surface( TopoDS::Face( aLocShape ) ); + if ( !aSurf.IsNull() && aSurf->DynamicType() == mySurfaceType ) + { + myElementsOnSurfacePtr->SetSurface( aLocShape, (SMDSAbs_ElementType)theType ); + return; + } + } + + myElementsOnSurfacePtr->SetSurface( TopoDS_Shape(), (SMDSAbs_ElementType)theType ); + } + + void BelongToSurface_i::SetShapeName( const char* theName, ElementType theType ) + { + CORBA::string_free( myShapeName ); + myShapeName = CORBA::string_dup( theName ); + myElementsOnSurfacePtr->SetSurface( getShapeByName( myShapeName ), (SMDSAbs_ElementType)theType ); + TPythonDump()<SetSurface( S, (SMDSAbs_ElementType)theType ); + } + + char* BelongToSurface_i::GetShapeName() + { + return CORBA::string_dup( myShapeName ); + } + + char* BelongToSurface_i::GetShapeID() + { + return CORBA::string_dup( myShapeID ); + } + + void BelongToSurface_i::SetTolerance( CORBA::Double theToler ) + { + myElementsOnSurfacePtr->SetTolerance( theToler ); + TPythonDump()<GetTolerance(); + } + + void BelongToSurface_i::SetUseBoundaries( CORBA::Boolean theUseBndRestrictions ) + { + myElementsOnSurfacePtr->SetUseBoundaries( theUseBndRestrictions ); + TPythonDump()<GetUseBoundaries(); + } + + + /* + Class : BelongToPlane_i + Description : Verify whether mesh element lie in pointed Geom planar object + */ + + BelongToPlane_i::BelongToPlane_i() + : BelongToSurface_i( STANDARD_TYPE( Geom_Plane ) ) + { + } + + void BelongToPlane_i::SetPlane( GEOM::GEOM_Object_ptr theGeom, ElementType theType ) + { + BelongToSurface_i::SetSurface( theGeom, theType ); + TPythonDump()<_is_nil() ) + return; + TopoDS_Shape aLocShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( theGeom ); + if ( !aLocShape.IsNull() && aLocShape.ShapeType() != TopAbs_FACE ) + aLocShape.Nullify(); + + BelongToSurface_i::myElementsOnSurfacePtr->SetSurface( aLocShape, (SMDSAbs_ElementType)theType ); + TPythonDump()<_is_nil() ) + return; + TopoDS_Shape aLocShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( theGeom ); + myLyingOnGeomPtr->SetGeom( aLocShape ); + TPythonDump()<SetGeom( theShape ); + } + + void LyingOnGeom_i::SetElementType(ElementType theType){ + myLyingOnGeomPtr->SetType(SMDSAbs_ElementType(theType)); + TPythonDump()<SetGeom( getShapeByName( myShapeName ) ); + TPythonDump()<SetGeom( S ); + } + + char* LyingOnGeom_i::GetShapeName() + { + return CORBA::string_dup( myShapeName ); + } + + char* LyingOnGeom_i::GetShapeID() + { + return CORBA::string_dup( myShapeID ); + } + + void LyingOnGeom_i::SetTolerance( CORBA::Double theToler ) + { + myLyingOnGeomPtr->SetTolerance( theToler ); + TPythonDump()<GetTolerance(); + } + + /* + Class : FreeBorders_i + Description : Predicate for free borders + */ + FreeBorders_i::FreeBorders_i() + { + myPredicatePtr.reset(new Controls::FreeBorders()); + myFunctorPtr = myPredicatePtr; + } + + FunctorType FreeBorders_i::GetFunctorType() + { + return SMESH::FT_FreeBorders; + } + + /* + Class : FreeEdges_i + Description : Predicate for free borders + */ + FreeEdges_i::FreeEdges_i() + : myFreeEdgesPtr( new Controls::FreeEdges() ) + { + myFunctorPtr = myPredicatePtr = myFreeEdgesPtr; + } + + SMESH::FreeEdges::Borders* FreeEdges_i::GetBorders() + { + SMESH::Controls::FreeEdges::TBorders aBorders; + myFreeEdgesPtr->GetBoreders( aBorders ); + + long i = 0, iEnd = aBorders.size(); + + SMESH::FreeEdges::Borders_var aResult = new SMESH::FreeEdges::Borders; + aResult->length(iEnd); + + SMESH::Controls::FreeEdges::TBorders::const_iterator anIter; + for ( anIter = aBorders.begin() ; anIter != aBorders.end(); anIter++, i++ ) + { + const SMESH::Controls::FreeEdges::Border& aBord = *anIter; + SMESH::FreeEdges::Border &aBorder = aResult[ i ]; + + aBorder.myElemId = aBord.myElemId; + aBorder.myPnt1 = aBord.myPntId[ 0 ]; + aBorder.myPnt2 = aBord.myPntId[ 1 ]; + } + return aResult._retn(); + } + + FunctorType FreeEdges_i::GetFunctorType() + { + return SMESH::FT_FreeEdges; + } + + /* + Class : FreeFaces_i + Description : Predicate for free faces + */ + FreeFaces_i::FreeFaces_i() + { + myPredicatePtr.reset(new Controls::FreeFaces()); + myFunctorPtr = myPredicatePtr; + } + + FunctorType FreeFaces_i::GetFunctorType() + { + return SMESH::FT_FreeFaces; + } + + /* + Class : FreeNodes_i + Description : Predicate for free nodes + */ + FreeNodes_i::FreeNodes_i() + { + myPredicatePtr.reset(new Controls::FreeNodes()); + myFunctorPtr = myPredicatePtr; + } + + FunctorType FreeNodes_i::GetFunctorType() + { + return SMESH::FT_FreeNodes; + } + + /* + Class : EqualNodes_i + Description : Predicate for Equal nodes + */ + EqualNodes_i::EqualNodes_i() + { + myCoincidentNodesPtr.reset(new Controls::CoincidentNodes()); + myFunctorPtr = myPredicatePtr = myCoincidentNodesPtr; + } + + FunctorType EqualNodes_i::GetFunctorType() + { + return SMESH::FT_EqualNodes; + } + + void EqualNodes_i::SetTolerance( double tol ) + { + myCoincidentNodesPtr->SetTolerance( tol ); + } + + double EqualNodes_i::GetTolerance() + { + return myCoincidentNodesPtr->GetTolerance(); + } + + /* + Class : EqualEdges_i + Description : Predicate for Equal Edges + */ + EqualEdges_i::EqualEdges_i() + { + myPredicatePtr.reset(new Controls::CoincidentElements1D()); + myFunctorPtr = myPredicatePtr; + } + + FunctorType EqualEdges_i::GetFunctorType() + { + return SMESH::FT_EqualEdges; + } + + /* + Class : EqualFaces_i + Description : Predicate for Equal Faces + */ + EqualFaces_i::EqualFaces_i() + { + myPredicatePtr.reset(new Controls::CoincidentElements2D()); + myFunctorPtr = myPredicatePtr; + } + + FunctorType EqualFaces_i::GetFunctorType() + { + return SMESH::FT_EqualFaces; + } + + /* + Class : EqualVolumes_i + Description : Predicate for Equal Volumes + */ + EqualVolumes_i::EqualVolumes_i() + { + myPredicatePtr.reset(new Controls::CoincidentElements3D()); + myFunctorPtr = myPredicatePtr; + } + + FunctorType EqualVolumes_i::GetFunctorType() + { + return SMESH::FT_EqualVolumes; + } + + + /* + Class : RangeOfIds_i + Description : Predicate for Range of Ids. + Range may be specified with two ways. + 1. Using AddToRange method + 2. With SetRangeStr method. Parameter of this method is a string + like as "1,2,3,50-60,63,67,70-" + */ + + RangeOfIds_i::RangeOfIds_i() + { + myRangeOfIdsPtr.reset( new Controls::RangeOfIds() ); + myFunctorPtr = myPredicatePtr = myRangeOfIdsPtr; + } + + void RangeOfIds_i::SetRange( const SMESH::smIdType_array& theIds ) + { + SMESH::smIdType iEnd = theIds.length(); + for ( SMESH::smIdType i = 0; i < iEnd; i++ ) + myRangeOfIdsPtr->AddToRange( theIds[ i ] ); + TPythonDump()<SetRangeStr( + TCollection_AsciiString( (Standard_CString)theRange ) ); + } + + char* RangeOfIds_i::GetRangeStr() + { + TCollection_AsciiString aStr; + myRangeOfIdsPtr->GetRangeStr( aStr ); + return CORBA::string_dup( aStr.ToCString() ); + } + + void RangeOfIds_i::SetElementType( ElementType theType ) + { + myRangeOfIdsPtr->SetType( SMDSAbs_ElementType( theType ) ); + TPythonDump()<SetType(SMDSAbs_ElementType(theType)); + TPythonDump()<SetColorStr( + TCollection_AsciiString( (Standard_CString)theColor ) ); + TPythonDump()<GetColorStr( aStr ); + return CORBA::string_dup( aStr.ToCString() ); + } + + void GroupColor_i::SetElementType(ElementType theType) + { + myGroupColorPtr->SetType(SMDSAbs_ElementType(theType)); + TPythonDump()<SetType(SMDSAbs_ElementType(theType)); + TPythonDump()<SetGeomType(SMDSAbs_GeometryType(theType)); + TPythonDump()<GetGeomType(); + } + + FunctorType ElemGeomType_i::GetFunctorType() + { + return SMESH::FT_ElemGeomType; + } + + /* + Class : ElemEntityType_i + Description : Predicate check is element has indicated entity type + */ + ElemEntityType_i::ElemEntityType_i() + { + myElemEntityTypePtr.reset(new Controls::ElemEntityType()); + myFunctorPtr = myPredicatePtr = myElemEntityTypePtr; + } + + void ElemEntityType_i::SetElementType(ElementType theType) + { + myElemEntityTypePtr->SetType(SMDSAbs_ElementType(theType)); + TPythonDump()<SetElemEntityType(SMDSAbs_EntityType (theEntityType)); + TPythonDump()<GetElemEntityType(); + } + + FunctorType ElemEntityType_i::GetFunctorType() + { + return SMESH::FT_EntityType; + } + + /* + Class : CoplanarFaces_i + Description : Returns true if a mesh face is a coplanar neighbour to a given one + */ + CoplanarFaces_i::CoplanarFaces_i() + { + myCoplanarFacesPtr.reset(new Controls::CoplanarFaces()); + myFunctorPtr = myPredicatePtr = myCoplanarFacesPtr; + } + + void CoplanarFaces_i::SetFace ( CORBA::Long theFaceID ) + { + myCoplanarFacesPtr->SetFace(theFaceID); + TPythonDump()<SetTolerance(theToler); + TPythonDump()<GetFace(); + } + + char* CoplanarFaces_i::GetFaceAsString () const + { + TCollection_AsciiString str(Standard_Integer(myCoplanarFacesPtr->GetFace())); + return CORBA::string_dup( str.ToCString() ); + } + + CORBA::Double CoplanarFaces_i::GetTolerance() const + { + return myCoplanarFacesPtr->GetTolerance(); + } + + FunctorType CoplanarFaces_i::GetFunctorType() + { + return SMESH::FT_CoplanarFaces; + } + + /* + * Class : ConnectedElements_i + * Description : Returns true if an element is connected via other elements to the element + * located at a given point. + */ + ConnectedElements_i::ConnectedElements_i() + { + myConnectedElementsPtr.reset(new Controls::ConnectedElements()); + myFunctorPtr = myPredicatePtr = myConnectedElementsPtr; + } + + FunctorType ConnectedElements_i::GetFunctorType() + { + return FT_ConnectedElements; + } + + void ConnectedElements_i::SetElementType( ElementType theType ) + { + myConnectedElementsPtr->SetType( SMDSAbs_ElementType( theType )); + TPythonDump() << this << ".SetElementType( " << theType << " )"; + } + + void ConnectedElements_i::SetPoint( CORBA::Double x, CORBA::Double y, CORBA::Double z ) + { + myConnectedElementsPtr->SetPoint( x,y,z ); + myVertexID.clear(); + TPythonDump() << this << ".SetPoint( " << x << ", " << y << ", " << z << " )"; + } + + void ConnectedElements_i::SetVertex( GEOM::GEOM_Object_ptr vertex ) + { + TopoDS_Shape shape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( vertex ); + if ( shape.IsNull() ) + THROW_SALOME_CORBA_EXCEPTION( "ConnectedElements_i::SetVertex(): NULL Vertex", + SALOME::BAD_PARAM ); + + TopExp_Explorer v( shape, TopAbs_VERTEX ); + if ( !v.More() ) + THROW_SALOME_CORBA_EXCEPTION( "ConnectedElements_i::SetVertex(): empty vertex", + SALOME::BAD_PARAM ); + + gp_Pnt p = BRep_Tool::Pnt( TopoDS::Vertex( v.Current() )); + myConnectedElementsPtr->SetPoint( p.X(), p.Y(), p.Z() ); + // + CORBA::String_var id = vertex->GetStudyEntry(); + myVertexID = id.in(); + + TPythonDump() << this << ".SetVertex( " << vertex << " )"; + } + + void ConnectedElements_i::SetNode ( SMESH::smIdType nodeID ) + { + if ( nodeID < 1 ) + THROW_SALOME_CORBA_EXCEPTION( "ConnectedElements_i::SetNode(): nodeID must be > 0", + SALOME::BAD_PARAM ); + + myConnectedElementsPtr->SetNode( nodeID ); + myVertexID.clear(); + TPythonDump() << this << ".SetNode( " << nodeID << " )"; + } + + /*! + * \brief This is a comfort method for Filter dialog + */ + void ConnectedElements_i::SetThreshold ( const char* threshold, + SMESH::ConnectedElements::ThresholdType type ) + { + if ( !threshold ) + THROW_SALOME_CORBA_EXCEPTION( "ConnectedElements_i::SetThreshold(): NULL threshold", + SALOME::BAD_PARAM ); + switch ( type ) + { + case SMESH::ConnectedElements::POINT: // read 3 node coordinates /////////////////// + { + std::vector< double > xyz; + char* endptr; + do + { + // skip a separator + while ( *threshold && + *threshold != '+' && + *threshold != '-' && + !isdigit( *threshold )) + ++threshold; + if ( !*threshold ) + break; + // read a coordinate + xyz.push_back( strtod( threshold, &endptr )); + if ( threshold == endptr ) + { + xyz.resize( xyz.size() - 1 ); + break; + } + threshold = endptr; + } + while ( xyz.size() < 3 ); + + if ( xyz.size() < 3 ) + THROW_SALOME_CORBA_EXCEPTION + ( "ConnectedElements_i::SetThreshold(): invalid point coordinates", SALOME::BAD_PARAM ); + + SetPoint( xyz[0], xyz[1], xyz[2] ); + break; + } + case SMESH::ConnectedElements::VERTEX: // get a VERTEX by its entry ///////////////// + { + SALOMEDS::SObject_wrap sobj = SMESH_Gen_i::GetSMESHGen()->getStudyServant()->FindObjectID( threshold ); + if ( sobj->_is_nil() ) + THROW_SALOME_CORBA_EXCEPTION + ( "ConnectedElements_i::SetThreshold(): invalid vertex study entry", SALOME::BAD_PARAM ); + CORBA::Object_var obj = sobj->GetObject(); + GEOM::GEOM_Object_var vertex = GEOM::GEOM_Object::_narrow( obj ); + if ( vertex->_is_nil() ) + THROW_SALOME_CORBA_EXCEPTION + ( "ConnectedElements_i::SetThreshold(): no GEOM_Object in SObject", SALOME::BAD_PARAM ); + SetVertex( vertex ); + break; + } + case SMESH::ConnectedElements::NODE: // read a node ID //////////////////////////// + { + char* endptr; + int id = strtol( threshold, &endptr, 10 ); + if ( threshold == endptr ) + THROW_SALOME_CORBA_EXCEPTION + ( "ConnectedElements_i::SetThreshold(): invalid node ID", SALOME::BAD_PARAM ); + SetNode( id ); + break; + } + default: + THROW_SALOME_CORBA_EXCEPTION + ( "ConnectedElements_i::SetThreshold(): invalid ThresholdType", SALOME::BAD_PARAM ); + } + } + + char* ConnectedElements_i::GetThreshold ( SMESH::ConnectedElements::ThresholdType& type ) + { + std::string threshold; + if ( !myVertexID.empty() ) + { + threshold = myVertexID; + type = SMESH::ConnectedElements::VERTEX; + } + else + { + std::vector xyz = myConnectedElementsPtr->GetPoint(); + if ( xyz.size() == 3 ) + { + threshold = SMESH_Comment( xyz[0] ) << "; " << xyz[1] << "; " << xyz[2]; + type = SMESH::ConnectedElements::POINT; + } + else + { + threshold = SMESH_Comment( myConnectedElementsPtr->GetNode() ); + type = SMESH::ConnectedElements::NODE; + } + } + return CORBA::string_dup( threshold.c_str() ); + } + + /* + Class : Comparator_i + Description : Base class for comparators + */ + Comparator_i::Comparator_i(): + myNumericalFunctor( NULL ) + {} + + Comparator_i::~Comparator_i() + { + if ( myNumericalFunctor ) + myNumericalFunctor->UnRegister(); + } + + void Comparator_i::SetMargin( CORBA::Double theValue ) + { + myComparatorPtr->SetMargin( theValue ); + TPythonDump()<GetMargin(); + } + + void Comparator_i::SetNumFunctor( NumericalFunctor_ptr theFunct ) + { + if ( myNumericalFunctor ) + myNumericalFunctor->UnRegister(); + + myNumericalFunctor = DownCast(theFunct); + + if ( myNumericalFunctor ) + { + myComparatorPtr->SetNumFunctor( myNumericalFunctor->GetNumericalFunctor() ); + myNumericalFunctor->Register(); + TPythonDump()<" + */ + MoreThan_i::MoreThan_i() + { + myComparatorPtr.reset( new Controls::MoreThan() ); + myFunctorPtr = myPredicatePtr = myComparatorPtr; + } + + FunctorType MoreThan_i::GetFunctorType() + { + return SMESH::FT_MoreThan; + } + + + /* + Class : EqualTo_i + Description : Comparator "=" + */ + EqualTo_i::EqualTo_i() + : myEqualToPtr( new Controls::EqualTo() ) + { + myFunctorPtr = myPredicatePtr = myComparatorPtr = myEqualToPtr; + } + + void EqualTo_i::SetTolerance( CORBA::Double theToler ) + { + myEqualToPtr->SetTolerance( theToler ); + TPythonDump()<GetTolerance(); + } + + FunctorType EqualTo_i::GetFunctorType() + { + return SMESH::FT_EqualTo; + } + + /* + Class : LogicalNOT_i + Description : Logical NOT predicate + */ + LogicalNOT_i::LogicalNOT_i(): + myLogicalNOTPtr( new Controls::LogicalNOT() ), + myPredicate( NULL ) + { + myFunctorPtr = myPredicatePtr = myLogicalNOTPtr; + } + + LogicalNOT_i::~LogicalNOT_i() + { + if ( myPredicate ) + myPredicate->UnRegister(); + } + + void LogicalNOT_i::SetPredicate( Predicate_ptr thePredicate ) + { + if ( myPredicate ) + myPredicate->UnRegister(); + + myPredicate = SMESH::GetPredicate(thePredicate); + + if ( myPredicate ){ + myLogicalNOTPtr->SetPredicate(myPredicate->GetPredicate()); + myPredicate->Register(); + TPythonDump()<UnRegister(); + + if ( myPredicate2 ) + myPredicate2->UnRegister(); + } + + void LogicalBinary_i::SetMesh( SMESH_Mesh_ptr theMesh ) + { + if ( myPredicate1 ) + myPredicate1->SetMesh( theMesh ); + + if ( myPredicate2 ) + myPredicate2->SetMesh( theMesh ); + } + + void LogicalBinary_i::SetPredicate1( Predicate_ptr thePredicate ) + { + if ( myPredicate1 ) + myPredicate1->UnRegister(); + + myPredicate1 = SMESH::GetPredicate(thePredicate); + + if ( myPredicate1 ){ + myLogicalBinaryPtr->SetPredicate1(myPredicate1->GetPredicate()); + myPredicate1->Register(); + TPythonDump()<UnRegister(); + + myPredicate2 = SMESH::GetPredicate(thePredicate); + + if ( myPredicate2 ){ + myLogicalBinaryPtr->SetPredicate2(myPredicate2->GetPredicate()); + myPredicate2->Register(); + TPythonDump()<activate_object( this ); + } + + + FilterManager_i::~FilterManager_i() + { + //TPythonDump()<_this(); + TPythonDump()<_this(); + TPythonDump()<_this(); + TPythonDump()<_this(); + TPythonDump()<_this(); + TPythonDump()<_this(); + TPythonDump()<_this(); + TPythonDump()<_this(); + TPythonDump()<_this(); + TPythonDump()<_this(); + TPythonDump()<_this(); + TPythonDump()<_this(); + TPythonDump()<_this(); + TPythonDump()<_this(); + TPythonDump()<_this(); + TPythonDump()<_this(); + TPythonDump()<_this(); + TPythonDump()<_this(); + TPythonDump()<_this(); + TPythonDump()<_this(); + TPythonDump()<_this(); + TPythonDump()<_this(); + TPythonDump()<_this(); + TPythonDump()<_this(); + TPythonDump()<_this(); + TPythonDump()<_this(); + TPythonDump()<_this(); + TPythonDump()<_this(); + TPythonDump()<_this(); + TPythonDump()<_this(); + TPythonDump()<_this(); + TPythonDump()<_this(); + TPythonDump()<_this(); + TPythonDump()<_this(); + TPythonDump()<_this(); + TPythonDump()<_this(); + TPythonDump()<_this(); + TPythonDump()<_this(); + TPythonDump()<_this(); + TPythonDump()<_this(); + TPythonDump()<_this(); + TPythonDump()<_this(); + TPythonDump()<_this(); + TPythonDump()<_this(); + TPythonDump()<_this(); + TPythonDump()<_this(); + TPythonDump()<_this(); + TPythonDump()<_this(); + TPythonDump()<_this(); + TPythonDump()<_this(); + TPythonDump()<_this(); + TPythonDump()<_this(); + TPythonDump()<_this(); + TPythonDump()<UnRegister(); + + if(!CORBA::is_nil(myMesh)) + myMesh->UnRegister(); + + myPredicate = 0; + FindBaseObjects(); + } + + //======================================================================= + // name : Filter_i::SetPredicate + // Purpose : Set predicate + //======================================================================= + void Filter_i::SetPredicate( Predicate_ptr thePredicate ) + { + if ( myPredicate ) + myPredicate->UnRegister(); + + myPredicate = SMESH::GetPredicate(thePredicate); + + if ( myPredicate ) + { + myFilter.SetPredicate( myPredicate->GetPredicate() ); + myPredicate->Register(); + if ( const SMDS_Mesh* aMesh = MeshPtr2SMDSMesh(myMesh)) + myPredicate->GetPredicate()->SetMesh( aMesh ); + TPythonDump()<GetElementType() : SMESH::ALL; + } + + //======================================================================= + // name : Filter_i::SetMesh + // Purpose : Set mesh + //======================================================================= + void + Filter_i:: + SetMesh( SMESH_Mesh_ptr theMesh ) + { + if(!CORBA::is_nil(theMesh)) + theMesh->Register(); + + if(!CORBA::is_nil(myMesh)) + myMesh->UnRegister(); + + myMesh = SMESH_Mesh::_duplicate( theMesh ); + TPythonDump()<GetPredicate()->SetMesh( aMesh ); + } + + SMESH::smIdType_array* + Filter_i:: + GetIDs() + { + return GetElementsId(myMesh); + } + + //======================================================================= + // name : Filter_i::GetElementsId + // Purpose : Get ids of entities + //======================================================================= + void + Filter_i:: + GetElementsId( Predicate_i* thePredicate, + const SMDS_Mesh* theMesh, + Controls::Filter::TIdSequence& theSequence ) + { + if (thePredicate) + Controls::Filter::GetElementsId(theMesh,thePredicate->GetPredicate(),theSequence); + } + + void + Filter_i:: + GetElementsId( Predicate_i* thePredicate, + SMESH_Mesh_ptr theMesh, + Controls::Filter::TIdSequence& theSequence ) + { + if (thePredicate) + if(const SMDS_Mesh* aMesh = MeshPtr2SMDSMesh(theMesh)) + Controls::Filter::GetElementsId(aMesh,thePredicate->GetPredicate(),theSequence); + } + + SMESH::smIdType_array* + Filter_i:: + GetElementsId( SMESH_Mesh_ptr theMesh ) + { + SMESH::smIdType_array_var anArray = new SMESH::smIdType_array; + if(!CORBA::is_nil(theMesh) && myPredicate){ + theMesh->Load(); + Controls::Filter::TIdSequence aSequence; + GetElementsId(myPredicate,theMesh,aSequence); + long i = 0, iEnd = aSequence.size(); + anArray->length( iEnd ); + for ( ; i < iEnd; i++ ) + anArray[ i ] = aSequence[i]; + } + return anArray._retn(); + } + + SMESH::smIdType_array* + Filter_i:: + GetElementsIdFromParts( const ListOfIDSources& theParts ) + { + SMESH::smIdType_array_var array = new SMESH::smIdType_array; + if ( theParts.length() > 0 && myPredicate ) + { + SMESH_Mesh_ptr mesh = theParts[0]->GetMesh(); + mesh->Load(); + const SMDS_Mesh* meshDS = MeshPtr2SMDSMesh( mesh ); + Controls::Filter::TIdSequence totalSequence; + for ( CORBA::ULong i = 0; i < theParts.length(); ++i ) + { + if ( SMESH::Filter_i* filter = SMESH::DownCast( theParts[i] )) + filter->SetMesh( mesh ); + SMDS_ElemIteratorPtr iter = SMESH_Mesh_i::GetElements( theParts[i], GetElementType() ); + if ( iter && meshDS ) + { + Controls::Filter::TIdSequence sequence; + Controls::Filter::GetElementsId( meshDS, myPredicate->GetPredicate(), sequence, iter ); + totalSequence.insert( totalSequence.end(), sequence.begin(), sequence.end() ); + } + } + array->length( totalSequence.size() ); + for ( size_t i = 0; i < totalSequence.size(); ++i ) + array[ i ] = totalSequence[ i ]; + } + return array._retn(); + } + + //============================================================================= + /*! + * \brief Returns number of mesh elements per each \a EntityType + */ + //============================================================================= + + SMESH::smIdType_array* Filter_i::GetMeshInfo() + { + SMESH::smIdType_array_var aRes = new SMESH::smIdType_array(); + aRes->length(SMESH::Entity_Last); + for (int i = 0; i < SMESH::Entity_Last; i++) + aRes[i] = 0; + + if ( !CORBA::is_nil(myMesh) && myPredicate ) + { + const SMDS_Mesh* aMesh = MeshPtr2SMDSMesh(myMesh); + SMDS_ElemIteratorPtr it = aMesh->elementsIterator( SMDSAbs_ElementType( GetElementType() )); + while ( it->more() ) + { + const SMDS_MeshElement* anElem = it->next(); + if ( myPredicate->IsSatisfy( anElem->GetID() ) ) + aRes[ anElem->GetEntityType() ]++; + } + } + + return aRes._retn(); + } + + //============================================================================= + /*! + * \brief Returns number of mesh elements of each \a ElementType + */ + //============================================================================= + + SMESH::smIdType_array* Filter_i::GetNbElementsByType() + { + SMESH::smIdType_array_var aRes = new SMESH::smIdType_array(); + aRes->length(SMESH::NB_ELEMENT_TYPES); + for (int i = 0; i < SMESH::NB_ELEMENT_TYPES; i++) + aRes[i] = 0; + + if ( !CORBA::is_nil(myMesh) && myPredicate ) { + const SMDS_Mesh* aMesh = MeshPtr2SMDSMesh(myMesh); + SMDS_ElemIteratorPtr it = aMesh->elementsIterator( SMDSAbs_ElementType( GetElementType() )); + SMESH::smIdType& nbElems = aRes[ GetElementType() ]; + while ( it->more() ) + { + const SMDS_MeshElement* anElem = it->next(); + if ( myPredicate->IsSatisfy( anElem->GetID() ) ) + nbElems++; + } + } + + return aRes._retn(); + } + + + //================================================================================ + /*! + * \brief Return GetElementType() within an array + * Implement SMESH_IDSource interface + */ + //================================================================================ + + SMESH::array_of_ElementType* Filter_i::GetTypes() + { + SMESH::array_of_ElementType_var types = new SMESH::array_of_ElementType; + + // check if any element passes through the filter + if ( !CORBA::is_nil(myMesh) && myPredicate ) + { + const SMDS_Mesh* aMesh = MeshPtr2SMDSMesh(myMesh); + SMDS_ElemIteratorPtr it = aMesh->elementsIterator( SMDSAbs_ElementType( GetElementType() )); + bool satisfies = false; + while ( !satisfies && it->more() ) + satisfies = myPredicate->IsSatisfy( it->next()->GetID() ); + if ( satisfies ) { + types->length( 1 ); + types[0] = GetElementType(); + } + } + return types._retn(); + } + + //======================================================================= + //function : GetMesh + //purpose : Returns mesh + //======================================================================= + + SMESH::SMESH_Mesh_ptr Filter_i::GetMesh() + { + return SMESH_Mesh::_duplicate( myMesh ); + } + + //======================================================================= + //function : GetVtkUgStream + //purpose : Return data vtk unstructured grid (not implemented) + //======================================================================= + + SALOMEDS::TMPFile* Filter_i::GetVtkUgStream() + { + SALOMEDS::TMPFile_var SeqFile; + return SeqFile._retn(); + } + //======================================================================= + // name : getCriteria + // Purpose : Retrieve criterions from predicate + //======================================================================= + static inline void getPrediacates( Predicate_i* thePred, + std::vector & thePredVec ) + { + const int aFType = thePred->GetFunctorType(); + + switch ( aFType ) + { + case FT_LogicalNOT: { Predicate_i* aPred = ( dynamic_cast( thePred ) )->GetPredicate_i(); - getCriteria( aPred, theCriteria ); - theCriteria[ theCriteria->length() - 1 ].UnaryOp = FT_LogicalNOT; + getPrediacates( aPred, thePredVec ); + break; } - return true; - - case FT_LogicalAND: - case FT_LogicalOR: + case FT_LogicalAND: + case FT_LogicalOR: { Predicate_i* aPred1 = ( dynamic_cast( thePred ) )->GetPredicate1_i(); Predicate_i* aPred2 = ( dynamic_cast( thePred ) )->GetPredicate2_i(); - if ( !getCriteria( aPred1, theCriteria ) ) - return false; - theCriteria[ theCriteria->length() - 1 ].BinaryOp = aFType; - return getCriteria( aPred2, theCriteria ); + getPrediacates( aPred1, thePredVec ); + getPrediacates( aPred2, thePredVec ); + break; + } + default:; } - case FT_Undefined: - return false; + thePredVec.push_back( thePred ); } - // resize theCriteria - CORBA::ULong i = theCriteria->length(); - theCriteria->length( i + 1 ); - theCriteria[ i ] = createCriterion(); - - // set members of the added Criterion - - theCriteria[ i ].Type = aFType; - theCriteria[ i ].TypeOfElement = thePred->GetElementType(); - - switch ( aFType ) + //======================================================================= + // name : getCriteria + // Purpose : Retrieve criterions from predicate + //======================================================================= + static inline bool getCriteria( Predicate_i* thePred, + SMESH::Filter::Criteria_out theCriteria ) { - case FT_FreeBorders: - case FT_FreeEdges: - case FT_FreeFaces: - case FT_LinearOrQuadratic: - case FT_FreeNodes: - case FT_EqualEdges: - case FT_EqualFaces: - case FT_EqualVolumes: - case FT_BadOrientedVolume: - case FT_BareBorderVolume: - case FT_BareBorderFace: - case FT_OverConstrainedVolume: - case FT_OverConstrainedFace: + const int aFType = thePred->GetFunctorType(); + + switch ( aFType ) { - return true; - } - case FT_BelongToMeshGroup: - { - BelongToMeshGroup_i* aPred = dynamic_cast( thePred ); - SMESH::SMESH_GroupBase_var grp = aPred->GetGroup(); - if ( !grp->_is_nil() ) + case FT_LogicalNOT: { - theCriteria[ i ].ThresholdStr = grp->GetName(); - theCriteria[ i ].ThresholdID = aPred->GetGroupID().c_str(); + Predicate_i* aPred = ( dynamic_cast( thePred ) )->GetPredicate_i(); + getCriteria( aPred, theCriteria ); + theCriteria[ theCriteria->length() - 1 ].UnaryOp = FT_LogicalNOT; } return true; - } - case FT_BelongToGeom: - { - BelongToGeom_i* aPred = dynamic_cast( thePred ); - theCriteria[ i ].ThresholdStr = aPred->GetShapeName(); - theCriteria[ i ].ThresholdID = aPred->GetShapeID(); - theCriteria[ i ].Tolerance = aPred->GetTolerance(); - return true; - } - case FT_BelongToPlane: - case FT_BelongToCylinder: - case FT_BelongToGenSurface: - { - BelongToSurface_i* aPred = dynamic_cast( thePred ); - theCriteria[ i ].ThresholdStr = aPred->GetShapeName(); - theCriteria[ i ].ThresholdID = aPred->GetShapeID(); - theCriteria[ i ].Tolerance = aPred->GetTolerance(); - return true; - } - case FT_LyingOnGeom: - { - LyingOnGeom_i* aPred = dynamic_cast( thePred ); - theCriteria[ i ].ThresholdStr = aPred->GetShapeName(); - theCriteria[ i ].ThresholdID = aPred->GetShapeID(); - theCriteria[ i ].Tolerance = aPred->GetTolerance(); - return true; - } - case FT_CoplanarFaces: - { - CoplanarFaces_i* aPred = dynamic_cast( thePred ); - theCriteria[ i ].ThresholdID = aPred->GetFaceAsString(); - theCriteria[ i ].Tolerance = aPred->GetTolerance(); - return true; - } - case FT_ConnectedElements: - { - ConnectedElements_i* aPred = dynamic_cast( thePred ); - SMESH::ConnectedElements::ThresholdType type; - CORBA::String_var threshold = aPred->GetThreshold( type ); - switch ( type ) { - case SMESH::ConnectedElements::POINT: - theCriteria[ i ].ThresholdStr = threshold; break; - case SMESH::ConnectedElements::VERTEX: - theCriteria[ i ].ThresholdID = threshold; break; - case SMESH::ConnectedElements::NODE: - theCriteria[ i ].Threshold = atof( threshold.in() ); break; - default:; - } - return true; - } - case FT_EqualNodes: - { - EqualNodes_i* aPred = dynamic_cast( thePred ); - theCriteria[ i ].Tolerance = aPred->GetTolerance(); - return true; - } - case FT_RangeOfIds: - { - RangeOfIds_i* aPred = dynamic_cast( thePred ); - theCriteria[ i ].ThresholdStr = aPred->GetRangeStr(); - return true; - } - case FT_LessThan: - case FT_MoreThan: - case FT_EqualTo: - { - Comparator_i* aCompar = dynamic_cast( thePred ); - theCriteria[ i ].Type = aCompar->GetNumFunctor_i()->GetFunctorType(); - theCriteria[ i ].Compare = aFType; - theCriteria[ i ].Threshold = aCompar->GetMargin(); - if ( aFType == FT_EqualTo ) + + case FT_LogicalAND: + case FT_LogicalOR: { - EqualTo_i* aCompar = dynamic_cast( thePred ); - theCriteria[ i ].Tolerance = aCompar->GetTolerance(); + Predicate_i* aPred1 = ( dynamic_cast( thePred ) )->GetPredicate1_i(); + Predicate_i* aPred2 = ( dynamic_cast( thePred ) )->GetPredicate2_i(); + if ( !getCriteria( aPred1, theCriteria ) ) + return false; + theCriteria[ theCriteria->length() - 1 ].BinaryOp = aFType; + return getCriteria( aPred2, theCriteria ); } - return true; + case FT_Undefined: + return false; } - case FT_GroupColor: + + // resize theCriteria + CORBA::ULong i = theCriteria->length(); + theCriteria->length( i + 1 ); + theCriteria[ i ] = createCriterion(); + + // set members of the added Criterion + + theCriteria[ i ].Type = aFType; + theCriteria[ i ].TypeOfElement = thePred->GetElementType(); + + switch ( aFType ) { - GroupColor_i* aPred = dynamic_cast( thePred ); - theCriteria[ i ].ThresholdStr = aPred->GetColorStr(); - return true; + case FT_FreeBorders: + case FT_FreeEdges: + case FT_FreeFaces: + case FT_LinearOrQuadratic: + case FT_FreeNodes: + case FT_EqualEdges: + case FT_EqualFaces: + case FT_EqualVolumes: + case FT_BadOrientedVolume: + case FT_BareBorderVolume: + case FT_BareBorderFace: + case FT_OverConstrainedVolume: + case FT_OverConstrainedFace: + { + return true; + } + case FT_BelongToMeshGroup: + { + BelongToMeshGroup_i* aPred = dynamic_cast( thePred ); + SMESH::SMESH_GroupBase_var grp = aPred->GetGroup(); + if ( !grp->_is_nil() ) + { + theCriteria[ i ].ThresholdStr = grp->GetName(); + theCriteria[ i ].ThresholdID = aPred->GetGroupID().c_str(); + } + return true; + } + case FT_BelongToGeom: + { + BelongToGeom_i* aPred = dynamic_cast( thePred ); + theCriteria[ i ].ThresholdStr = aPred->GetShapeName(); + theCriteria[ i ].ThresholdID = aPred->GetShapeID(); + theCriteria[ i ].Tolerance = aPred->GetTolerance(); + return true; + } + case FT_BelongToPlane: + case FT_BelongToCylinder: + case FT_BelongToGenSurface: + { + BelongToSurface_i* aPred = dynamic_cast( thePred ); + theCriteria[ i ].ThresholdStr = aPred->GetShapeName(); + theCriteria[ i ].ThresholdID = aPred->GetShapeID(); + theCriteria[ i ].Tolerance = aPred->GetTolerance(); + return true; + } + case FT_LyingOnGeom: + { + LyingOnGeom_i* aPred = dynamic_cast( thePred ); + theCriteria[ i ].ThresholdStr = aPred->GetShapeName(); + theCriteria[ i ].ThresholdID = aPred->GetShapeID(); + theCriteria[ i ].Tolerance = aPred->GetTolerance(); + return true; + } + case FT_CoplanarFaces: + { + CoplanarFaces_i* aPred = dynamic_cast( thePred ); + theCriteria[ i ].ThresholdID = aPred->GetFaceAsString(); + theCriteria[ i ].Tolerance = aPred->GetTolerance(); + return true; + } + case FT_ConnectedElements: + { + ConnectedElements_i* aPred = dynamic_cast( thePred ); + SMESH::ConnectedElements::ThresholdType type; + CORBA::String_var threshold = aPred->GetThreshold( type ); + switch ( type ) { + case SMESH::ConnectedElements::POINT: + theCriteria[ i ].ThresholdStr = threshold; break; + case SMESH::ConnectedElements::VERTEX: + theCriteria[ i ].ThresholdID = threshold; break; + case SMESH::ConnectedElements::NODE: + theCriteria[ i ].Threshold = atof( threshold.in() ); break; + default:; + } + return true; + } + case FT_EqualNodes: + { + EqualNodes_i* aPred = dynamic_cast( thePred ); + theCriteria[ i ].Tolerance = aPred->GetTolerance(); + return true; + } + case FT_RangeOfIds: + { + RangeOfIds_i* aPred = dynamic_cast( thePred ); + theCriteria[ i ].ThresholdStr = aPred->GetRangeStr(); + return true; + } + case FT_LessThan: + case FT_MoreThan: + case FT_EqualTo: + { + Comparator_i* aCompar = dynamic_cast( thePred ); + theCriteria[ i ].Type = aCompar->GetNumFunctor_i()->GetFunctorType(); + theCriteria[ i ].Compare = aFType; + theCriteria[ i ].Threshold = aCompar->GetMargin(); + if ( aFType == FT_EqualTo ) + { + EqualTo_i* aCompar = dynamic_cast( thePred ); + theCriteria[ i ].Tolerance = aCompar->GetTolerance(); + } + return true; + } + case FT_GroupColor: + { + GroupColor_i* aPred = dynamic_cast( thePred ); + theCriteria[ i ].ThresholdStr = aPred->GetColorStr(); + return true; + } + case FT_ElemGeomType: + { + ElemGeomType_i* aPred = dynamic_cast( thePred ); + theCriteria[ i ].Threshold = (double)aPred->GetGeometryType(); + return true; + } + case FT_EntityType: + { + ElemEntityType_i* aPred = dynamic_cast( thePred ); + theCriteria[ i ].Threshold = (double)aPred->GetEntityType(); + return true; + } + default: + return false; } - case FT_ElemGeomType: - { - ElemGeomType_i* aPred = dynamic_cast( thePred ); - theCriteria[ i ].Threshold = (double)aPred->GetGeometryType(); - return true; - } - case FT_EntityType: - { - ElemEntityType_i* aPred = dynamic_cast( thePred ); - theCriteria[ i ].Threshold = (double)aPred->GetEntityType(); - return true; - } - default: - return false; } -} -//======================================================================= -// name : Filter_i::GetCriteria -// Purpose : Retrieve criterions from predicate -//======================================================================= -CORBA::Boolean Filter_i::GetCriteria( SMESH::Filter::Criteria_out theCriteria ) -{ - theCriteria = new SMESH::Filter::Criteria; - return myPredicate != 0 ? getCriteria( myPredicate, theCriteria ) : true; -} - -//======================================================================= -// name : Filter_i::SetCriteria -// Purpose : Create new predicate and set criterions in it -//======================================================================= -CORBA::Boolean Filter_i::SetCriteria( const SMESH::Filter::Criteria& theCriteria ) -{ - SetPredicate( SMESH::Predicate::_nil() ); - - SMESH::FilterManager_i* aFilter = new SMESH::FilterManager_i(); - FilterManager_ptr aFilterMgr = aFilter->_this(); - - // CREATE two lists ( PREDICATES and LOG OP ) - - // Criterion - TPythonDump()<<"aCriteria = []"; - std::list aPredicates; - std::list aBinaries; - for ( int i = 0, n = theCriteria.length(); i < n; i++ ) + //======================================================================= + // name : Filter_i::GetCriteria + // Purpose : Retrieve criterions from predicate + //======================================================================= + CORBA::Boolean Filter_i::GetCriteria( SMESH::Filter::Criteria_out theCriteria ) { - int aCriterion = theCriteria[ i ].Type; - int aCompare = theCriteria[ i ].Compare; - double aThreshold = theCriteria[ i ].Threshold; - const char* aThresholdStr = theCriteria[ i ].ThresholdStr; - const char* aThresholdID = theCriteria[ i ].ThresholdID; - int aUnary = theCriteria[ i ].UnaryOp; - int aBinary = theCriteria[ i ].BinaryOp; - double aTolerance = theCriteria[ i ].Tolerance; - ElementType aTypeOfElem = theCriteria[ i ].TypeOfElement; - long aPrecision = theCriteria[ i ].Precision; + theCriteria = new SMESH::Filter::Criteria; + return myPredicate != 0 ? getCriteria( myPredicate, theCriteria ) : true; + } + //======================================================================= + // name : Filter_i::SetCriteria + // Purpose : Create new predicate and set criterions in it + //======================================================================= + CORBA::Boolean Filter_i::SetCriteria( const SMESH::Filter::Criteria& theCriteria ) + { + SetPredicate( SMESH::Predicate::_nil() ); + + SMESH::FilterManager_i* aFilter = new SMESH::FilterManager_i(); + FilterManager_ptr aFilterMgr = aFilter->_this(); + + // CREATE two lists ( PREDICATES and LOG OP ) + + // Criterion + TPythonDump()<<"aCriteria = []"; + std::list aPredicates; + std::list aBinaries; + for ( int i = 0, n = theCriteria.length(); i < n; i++ ) { + int aCriterion = theCriteria[ i ].Type; + int aCompare = theCriteria[ i ].Compare; + double aThreshold = theCriteria[ i ].Threshold; + const char* aThresholdStr = theCriteria[ i ].ThresholdStr; + const char* aThresholdID = theCriteria[ i ].ThresholdID; + int aUnary = theCriteria[ i ].UnaryOp; + int aBinary = theCriteria[ i ].BinaryOp; + double aTolerance = theCriteria[ i ].Tolerance; + ElementType aTypeOfElem = theCriteria[ i ].TypeOfElement; + long aPrecision = theCriteria[ i ].Precision; + + { + TPythonDump pd; + pd << "aCriterion = SMESH.Filter.Criterion(" + << aCriterion << ", " + << aCompare << ", " + << aThreshold << ", '" + << aThresholdStr << "', '" + << aThresholdID << "', " + << aUnary << ", " + << aBinary << ", " + << aTolerance << ", " + << aTypeOfElem << ", " + << aPrecision << ")"; + } TPythonDump pd; - pd << "aCriterion = SMESH.Filter.Criterion(" - << aCriterion << ", " - << aCompare << ", " - << aThreshold << ", '" - << aThresholdStr << "', '" - << aThresholdID << "', " - << aUnary << ", " - << aBinary << ", " - << aTolerance << ", " - << aTypeOfElem << ", " - << aPrecision << ")"; - } - TPythonDump pd; - SMESH::Predicate_ptr aPredicate = SMESH::Predicate::_nil(); - SMESH::NumericalFunctor_ptr aFunctor = SMESH::NumericalFunctor::_nil(); + SMESH::Predicate_ptr aPredicate = SMESH::Predicate::_nil(); + SMESH::NumericalFunctor_ptr aFunctor = SMESH::NumericalFunctor::_nil(); - switch ( aCriterion ) - { - // Functors + switch ( aCriterion ) + { + // Functors - case SMESH::FT_MultiConnection: - aFunctor = aFilterMgr->CreateMultiConnection(); - break; - case SMESH::FT_MultiConnection2D: - aFunctor = aFilterMgr->CreateMultiConnection2D(); - break; - case SMESH::FT_Length: - aFunctor = aFilterMgr->CreateLength(); - break; - case SMESH::FT_Length2D: - aFunctor = aFilterMgr->CreateLength2D(); - break; - case SMESH::FT_Length3D: - aFunctor = aFilterMgr->CreateLength3D(); - break; - case SMESH::FT_Deflection2D: - aFunctor = aFilterMgr->CreateDeflection2D(); - break; - case SMESH::FT_AspectRatio: - aFunctor = aFilterMgr->CreateAspectRatio(); - break; - case SMESH::FT_AspectRatio3D: - aFunctor = aFilterMgr->CreateAspectRatio3D(); - break; - case SMESH::FT_Warping: - aFunctor = aFilterMgr->CreateWarping(); - break; - case SMESH::FT_MinimumAngle: - aFunctor = aFilterMgr->CreateMinimumAngle(); - break; - case SMESH::FT_Taper: - aFunctor = aFilterMgr->CreateTaper(); - break; - case SMESH::FT_Skew: - aFunctor = aFilterMgr->CreateSkew(); - break; - case SMESH::FT_Area: - aFunctor = aFilterMgr->CreateArea(); - break; - case SMESH::FT_Volume3D: - aFunctor = aFilterMgr->CreateVolume3D(); - break; - case SMESH::FT_MaxElementLength2D: - aFunctor = aFilterMgr->CreateMaxElementLength2D(); - break; - case SMESH::FT_MaxElementLength3D: - aFunctor = aFilterMgr->CreateMaxElementLength3D(); - break; - case SMESH::FT_BallDiameter: - aFunctor = aFilterMgr->CreateBallDiameter(); - break; - case SMESH::FT_NodeConnectivityNumber: - aFunctor = aFilterMgr->CreateNodeConnectivityNumber(); - break; - - // Predicates - - case SMESH::FT_FreeBorders: - aPredicate = aFilterMgr->CreateFreeBorders(); - break; - case SMESH::FT_FreeEdges: - aPredicate = aFilterMgr->CreateFreeEdges(); - break; - case SMESH::FT_FreeFaces: - aPredicate = aFilterMgr->CreateFreeFaces(); - break; - case SMESH::FT_FreeNodes: - aPredicate = aFilterMgr->CreateFreeNodes(); - break; - case SMESH::FT_EqualNodes: - { - SMESH::EqualNodes_ptr pred = aFilterMgr->CreateEqualNodes(); - pred->SetTolerance( aTolerance ); - aPredicate = pred; + case SMESH::FT_MultiConnection: + aFunctor = aFilterMgr->CreateMultiConnection(); break; - } - case SMESH::FT_EqualEdges: - aPredicate = aFilterMgr->CreateEqualEdges(); - break; - case SMESH::FT_EqualFaces: - aPredicate = aFilterMgr->CreateEqualFaces(); - break; - case SMESH::FT_EqualVolumes: - aPredicate = aFilterMgr->CreateEqualVolumes(); - break; - case SMESH::FT_BelongToMeshGroup: - { - SMESH::BelongToMeshGroup_ptr tmpPred = aFilterMgr->CreateBelongToMeshGroup(); - tmpPred->SetGroupID( aThresholdID ); - aPredicate = tmpPred; - } - break; - case SMESH::FT_BelongToGeom: - { - SMESH::BelongToGeom_ptr tmpPred = aFilterMgr->CreateBelongToGeom(); - tmpPred->SetElementType( aTypeOfElem ); - tmpPred->SetShape( aThresholdID, aThresholdStr ); - tmpPred->SetTolerance( aTolerance ); - aPredicate = tmpPred; - } - break; - case SMESH::FT_BelongToPlane: - case SMESH::FT_BelongToCylinder: - case SMESH::FT_BelongToGenSurface: - { - SMESH::BelongToSurface_ptr tmpPred; - switch ( aCriterion ) { - case SMESH::FT_BelongToPlane: - tmpPred = aFilterMgr->CreateBelongToPlane(); break; - case SMESH::FT_BelongToCylinder: - tmpPred = aFilterMgr->CreateBelongToCylinder(); break; - default: - tmpPred = aFilterMgr->CreateBelongToGenSurface(); + case SMESH::FT_MultiConnection2D: + aFunctor = aFilterMgr->CreateMultiConnection2D(); + break; + case SMESH::FT_Length: + aFunctor = aFilterMgr->CreateLength(); + break; + case SMESH::FT_Length2D: + aFunctor = aFilterMgr->CreateLength2D(); + break; + case SMESH::FT_Length3D: + aFunctor = aFilterMgr->CreateLength3D(); + break; + case SMESH::FT_Deflection2D: + aFunctor = aFilterMgr->CreateDeflection2D(); + break; + case SMESH::FT_AspectRatio: + aFunctor = aFilterMgr->CreateAspectRatio(); + break; + case SMESH::FT_AspectRatio3D: + aFunctor = aFilterMgr->CreateAspectRatio3D(); + break; + case SMESH::FT_Warping: + aFunctor = aFilterMgr->CreateWarping(); + break; + case SMESH::FT_MinimumAngle: + aFunctor = aFilterMgr->CreateMinimumAngle(); + break; + case SMESH::FT_Taper: + aFunctor = aFilterMgr->CreateTaper(); + break; + case SMESH::FT_Skew: + aFunctor = aFilterMgr->CreateSkew(); + break; + case SMESH::FT_Area: + aFunctor = aFilterMgr->CreateArea(); + break; + case SMESH::FT_Volume3D: + aFunctor = aFilterMgr->CreateVolume3D(); + break; + case SMESH::FT_MaxElementLength2D: + aFunctor = aFilterMgr->CreateMaxElementLength2D(); + break; + case SMESH::FT_MaxElementLength3D: + aFunctor = aFilterMgr->CreateMaxElementLength3D(); + break; + case SMESH::FT_BallDiameter: + aFunctor = aFilterMgr->CreateBallDiameter(); + break; + case SMESH::FT_NodeConnectivityNumber: + aFunctor = aFilterMgr->CreateNodeConnectivityNumber(); + break; + + // Predicates + + case SMESH::FT_FreeBorders: + aPredicate = aFilterMgr->CreateFreeBorders(); + break; + case SMESH::FT_FreeEdges: + aPredicate = aFilterMgr->CreateFreeEdges(); + break; + case SMESH::FT_FreeFaces: + aPredicate = aFilterMgr->CreateFreeFaces(); + break; + case SMESH::FT_FreeNodes: + aPredicate = aFilterMgr->CreateFreeNodes(); + break; + case SMESH::FT_EqualNodes: + { + SMESH::EqualNodes_ptr pred = aFilterMgr->CreateEqualNodes(); + pred->SetTolerance( aTolerance ); + aPredicate = pred; + break; } - tmpPred->SetShape( aThresholdID, aThresholdStr, aTypeOfElem ); - tmpPred->SetTolerance( aTolerance ); - aPredicate = tmpPred; - } - break; - case SMESH::FT_LyingOnGeom: - { - SMESH::LyingOnGeom_ptr tmpPred = aFilterMgr->CreateLyingOnGeom(); - tmpPred->SetElementType( aTypeOfElem ); - tmpPred->SetShape( aThresholdID, aThresholdStr ); - tmpPred->SetTolerance( aTolerance ); - aPredicate = tmpPred; - } - break; - case SMESH::FT_RangeOfIds: - { - SMESH::RangeOfIds_ptr tmpPred = aFilterMgr->CreateRangeOfIds(); - tmpPred->SetRangeStr( aThresholdStr ); - tmpPred->SetElementType( aTypeOfElem ); - aPredicate = tmpPred; - } - break; - case SMESH::FT_BadOrientedVolume: - { - aPredicate = aFilterMgr->CreateBadOrientedVolume(); - } - break; - case SMESH::FT_BareBorderVolume: - { - aPredicate = aFilterMgr->CreateBareBorderVolume(); - } - break; - case SMESH::FT_BareBorderFace: - { - aPredicate = aFilterMgr->CreateBareBorderFace(); - } - break; - case SMESH::FT_OverConstrainedVolume: - { - aPredicate = aFilterMgr->CreateOverConstrainedVolume(); - } - break; - case SMESH::FT_OverConstrainedFace: - { - aPredicate = aFilterMgr->CreateOverConstrainedFace(); - } - break; - case SMESH::FT_LinearOrQuadratic: - { - SMESH::LinearOrQuadratic_ptr tmpPred = aFilterMgr->CreateLinearOrQuadratic(); - tmpPred->SetElementType( aTypeOfElem ); - aPredicate = tmpPred; + case SMESH::FT_EqualEdges: + aPredicate = aFilterMgr->CreateEqualEdges(); break; - } - case SMESH::FT_GroupColor: - { - SMESH::GroupColor_ptr tmpPred = aFilterMgr->CreateGroupColor(); - tmpPred->SetElementType( aTypeOfElem ); - tmpPred->SetColorStr( aThresholdStr ); - aPredicate = tmpPred; + case SMESH::FT_EqualFaces: + aPredicate = aFilterMgr->CreateEqualFaces(); break; - } - case SMESH::FT_ElemGeomType: - { - SMESH::ElemGeomType_ptr tmpPred = aFilterMgr->CreateElemGeomType(); - tmpPred->SetElementType( aTypeOfElem ); - tmpPred->SetGeometryType( (GeometryType)(int)(aThreshold + 0.5) ); - aPredicate = tmpPred; + case SMESH::FT_EqualVolumes: + aPredicate = aFilterMgr->CreateEqualVolumes(); break; - } - case SMESH::FT_EntityType: - { - SMESH::ElemEntityType_ptr tmpPred = aFilterMgr->CreateElemEntityType(); - tmpPred->SetElementType( aTypeOfElem ); - tmpPred->SetEntityType( EntityType( (int (aThreshold + 0.5)))); - aPredicate = tmpPred; + case SMESH::FT_BelongToMeshGroup: + { + SMESH::BelongToMeshGroup_ptr tmpPred = aFilterMgr->CreateBelongToMeshGroup(); + tmpPred->SetGroupID( aThresholdID ); + aPredicate = tmpPred; + } break; - } - case SMESH::FT_CoplanarFaces: - { - SMESH::CoplanarFaces_ptr tmpPred = aFilterMgr->CreateCoplanarFaces(); - tmpPred->SetFace( atol (aThresholdID )); - tmpPred->SetTolerance( aTolerance ); - aPredicate = tmpPred; + case SMESH::FT_BelongToGeom: + { + SMESH::BelongToGeom_ptr tmpPred = aFilterMgr->CreateBelongToGeom(); + tmpPred->SetElementType( aTypeOfElem ); + tmpPred->SetShape( aThresholdID, aThresholdStr ); + tmpPred->SetTolerance( aTolerance ); + aPredicate = tmpPred; + } break; - } - case SMESH::FT_ConnectedElements: - { - SMESH::ConnectedElements_ptr tmpPred = aFilterMgr->CreateConnectedElements(); - if ( strlen( aThresholdID ) > 0 ) // shape ID - tmpPred->SetThreshold( aThresholdID, SMESH::ConnectedElements::VERTEX ); - else if ( strlen( aThresholdStr ) > 0 ) // point coords - tmpPred->SetThreshold( aThresholdStr, SMESH::ConnectedElements::POINT ); - else if ( aThreshold >= 1 ) - tmpPred->SetNode( (CORBA::Long) aThreshold ); // node ID - tmpPred->SetElementType( aTypeOfElem ); - aPredicate = tmpPred; + case SMESH::FT_BelongToPlane: + case SMESH::FT_BelongToCylinder: + case SMESH::FT_BelongToGenSurface: + { + SMESH::BelongToSurface_ptr tmpPred; + switch ( aCriterion ) { + case SMESH::FT_BelongToPlane: + tmpPred = aFilterMgr->CreateBelongToPlane(); break; + case SMESH::FT_BelongToCylinder: + tmpPred = aFilterMgr->CreateBelongToCylinder(); break; + default: + tmpPred = aFilterMgr->CreateBelongToGenSurface(); + } + tmpPred->SetShape( aThresholdID, aThresholdStr, aTypeOfElem ); + tmpPred->SetTolerance( aTolerance ); + aPredicate = tmpPred; + } break; + case SMESH::FT_LyingOnGeom: + { + SMESH::LyingOnGeom_ptr tmpPred = aFilterMgr->CreateLyingOnGeom(); + tmpPred->SetElementType( aTypeOfElem ); + tmpPred->SetShape( aThresholdID, aThresholdStr ); + tmpPred->SetTolerance( aTolerance ); + aPredicate = tmpPred; + } + break; + case SMESH::FT_RangeOfIds: + { + SMESH::RangeOfIds_ptr tmpPred = aFilterMgr->CreateRangeOfIds(); + tmpPred->SetRangeStr( aThresholdStr ); + tmpPred->SetElementType( aTypeOfElem ); + aPredicate = tmpPred; + } + break; + case SMESH::FT_BadOrientedVolume: + { + aPredicate = aFilterMgr->CreateBadOrientedVolume(); + } + break; + case SMESH::FT_BareBorderVolume: + { + aPredicate = aFilterMgr->CreateBareBorderVolume(); + } + break; + case SMESH::FT_BareBorderFace: + { + aPredicate = aFilterMgr->CreateBareBorderFace(); + } + break; + case SMESH::FT_OverConstrainedVolume: + { + aPredicate = aFilterMgr->CreateOverConstrainedVolume(); + } + break; + case SMESH::FT_OverConstrainedFace: + { + aPredicate = aFilterMgr->CreateOverConstrainedFace(); + } + break; + case SMESH::FT_LinearOrQuadratic: + { + SMESH::LinearOrQuadratic_ptr tmpPred = aFilterMgr->CreateLinearOrQuadratic(); + tmpPred->SetElementType( aTypeOfElem ); + aPredicate = tmpPred; + break; + } + case SMESH::FT_GroupColor: + { + SMESH::GroupColor_ptr tmpPred = aFilterMgr->CreateGroupColor(); + tmpPred->SetElementType( aTypeOfElem ); + tmpPred->SetColorStr( aThresholdStr ); + aPredicate = tmpPred; + break; + } + case SMESH::FT_ElemGeomType: + { + SMESH::ElemGeomType_ptr tmpPred = aFilterMgr->CreateElemGeomType(); + tmpPred->SetElementType( aTypeOfElem ); + tmpPred->SetGeometryType( (GeometryType)(int)(aThreshold + 0.5) ); + aPredicate = tmpPred; + break; + } + case SMESH::FT_EntityType: + { + SMESH::ElemEntityType_ptr tmpPred = aFilterMgr->CreateElemEntityType(); + tmpPred->SetElementType( aTypeOfElem ); + tmpPred->SetEntityType( EntityType( (int (aThreshold + 0.5)))); + aPredicate = tmpPred; + break; + } + case SMESH::FT_CoplanarFaces: + { + SMESH::CoplanarFaces_ptr tmpPred = aFilterMgr->CreateCoplanarFaces(); + tmpPred->SetFace( atol (aThresholdID )); + tmpPred->SetTolerance( aTolerance ); + aPredicate = tmpPred; + break; + } + case SMESH::FT_ConnectedElements: + { + SMESH::ConnectedElements_ptr tmpPred = aFilterMgr->CreateConnectedElements(); + if ( strlen( aThresholdID ) > 0 ) // shape ID + tmpPred->SetThreshold( aThresholdID, SMESH::ConnectedElements::VERTEX ); + else if ( strlen( aThresholdStr ) > 0 ) // point coords + tmpPred->SetThreshold( aThresholdStr, SMESH::ConnectedElements::POINT ); + else if ( aThreshold >= 1 ) + tmpPred->SetNode( (CORBA::Long) aThreshold ); // node ID + tmpPred->SetElementType( aTypeOfElem ); + aPredicate = tmpPred; + break; + } + + default: + continue; + } + + // Comparator + if ( !aFunctor->_is_nil() && aPredicate->_is_nil() ) + { + SMESH::Comparator_ptr aComparator = SMESH::Comparator::_nil(); + + if ( aCompare == SMESH::FT_LessThan ) + aComparator = aFilterMgr->CreateLessThan(); + else if ( aCompare == SMESH::FT_MoreThan ) + aComparator = aFilterMgr->CreateMoreThan(); + else if ( aCompare == SMESH::FT_EqualTo ) + aComparator = aFilterMgr->CreateEqualTo(); + else + continue; + + aComparator->SetNumFunctor( aFunctor ); + aComparator->SetMargin( aThreshold ); + + if ( aCompare == FT_EqualTo ) + { + SMESH::EqualTo_var anEqualTo = SMESH::EqualTo::_narrow( aComparator ); + anEqualTo->SetTolerance( aTolerance ); } - default: - continue; - } + aPredicate = aComparator; - // Comparator - if ( !aFunctor->_is_nil() && aPredicate->_is_nil() ) + aFunctor->SetPrecision( aPrecision ); + } + + // Logical not + if ( aUnary == FT_LogicalNOT ) + { + SMESH::LogicalNOT_ptr aNotPred = aFilterMgr->CreateLogicalNOT(); + aNotPred->SetPredicate( aPredicate ); + aPredicate = aNotPred; + } + + // logical op + aPredicates.push_back( aPredicate ); + aBinaries.push_back( aBinary ); + pd <<"aCriteria.append(aCriterion)"; + + } // end of for + TPythonDump pd; pd< aResList; + + std::list::iterator aPredIter; + std::list::iterator aBinaryIter; + + SMESH::Predicate_ptr aPrevPredicate = SMESH::Predicate::_nil(); + int aPrevBinary = SMESH::FT_Undefined; + if ( !aBinaries.empty() ) + aBinaries.back() = SMESH::FT_Undefined; + + for ( aPredIter = aPredicates.begin(), aBinaryIter = aBinaries.begin(); + aPredIter != aPredicates.end() && aBinaryIter != aBinaries.end(); + ++aPredIter, ++aBinaryIter ) { - SMESH::Comparator_ptr aComparator = SMESH::Comparator::_nil(); + int aCurrBinary = *aBinaryIter; - if ( aCompare == SMESH::FT_LessThan ) - aComparator = aFilterMgr->CreateLessThan(); - else if ( aCompare == SMESH::FT_MoreThan ) - aComparator = aFilterMgr->CreateMoreThan(); - else if ( aCompare == SMESH::FT_EqualTo ) - aComparator = aFilterMgr->CreateEqualTo(); + SMESH::Predicate_ptr aCurrPred = SMESH::Predicate::_nil(); + + if ( aPrevBinary == SMESH::FT_LogicalAND ) + { + + SMESH::LogicalBinary_ptr aBinaryPred = aFilterMgr->CreateLogicalAND(); + aBinaryPred->SetPredicate1( aPrevPredicate ); + aBinaryPred->SetPredicate2( *aPredIter ); + aCurrPred = aBinaryPred; + } else - continue; + aCurrPred = *aPredIter; - aComparator->SetNumFunctor( aFunctor ); - aComparator->SetMargin( aThreshold ); + if ( aCurrBinary != SMESH::FT_LogicalAND ) + aResList.push_back( aCurrPred ); - if ( aCompare == FT_EqualTo ) + aPrevPredicate = aCurrPred; + aPrevBinary = aCurrBinary; + } + + // combine all "OR" operations + + SMESH::Predicate_ptr aResPredicate = SMESH::Predicate::_nil(); + + if ( aResList.size() == 1 ) + aResPredicate = *aResList.begin(); + else if ( aResList.size() > 1 ) + { + std::list::iterator anIter = aResList.begin(); + aResPredicate = *anIter; + anIter++; + for ( ; anIter != aResList.end(); ++anIter ) { - SMESH::EqualTo_var anEqualTo = SMESH::EqualTo::_narrow( aComparator ); - anEqualTo->SetTolerance( aTolerance ); + SMESH::LogicalBinary_ptr aBinaryPred = aFilterMgr->CreateLogicalOR(); + aBinaryPred->SetPredicate1( aResPredicate ); + aBinaryPred->SetPredicate2( *anIter ); + aResPredicate = aBinaryPred; } - - aPredicate = aComparator; - - aFunctor->SetPrecision( aPrecision ); } - // Logical not - if ( aUnary == FT_LogicalNOT ) - { - SMESH::LogicalNOT_ptr aNotPred = aFilterMgr->CreateLogicalNOT(); - aNotPred->SetPredicate( aPredicate ); - aPredicate = aNotPred; - } + SetPredicate( aResPredicate ); + if ( !aResPredicate->_is_nil() ) + aResPredicate->UnRegister(); - // logical op - aPredicates.push_back( aPredicate ); - aBinaries.push_back( aBinary ); - pd <<"aCriteria.append(aCriterion)"; + return !aResPredicate->_is_nil(); + } - } // end of for - TPythonDump pd; pd< aResList; - - std::list::iterator aPredIter; - std::list::iterator aBinaryIter; - - SMESH::Predicate_ptr aPrevPredicate = SMESH::Predicate::_nil(); - int aPrevBinary = SMESH::FT_Undefined; - if ( !aBinaries.empty() ) - aBinaries.back() = SMESH::FT_Undefined; - - for ( aPredIter = aPredicates.begin(), aBinaryIter = aBinaries.begin(); - aPredIter != aPredicates.end() && aBinaryIter != aBinaries.end(); - ++aPredIter, ++aBinaryIter ) + //======================================================================= + // name : Filter_i::GetPredicate_i + // Purpose : Get implementation of predicate + //======================================================================= + Predicate_i* Filter_i::GetPredicate_i() { - int aCurrBinary = *aBinaryIter; + return myPredicate; + } - SMESH::Predicate_ptr aCurrPred = SMESH::Predicate::_nil(); - - if ( aPrevBinary == SMESH::FT_LogicalAND ) - { - - SMESH::LogicalBinary_ptr aBinaryPred = aFilterMgr->CreateLogicalAND(); - aBinaryPred->SetPredicate1( aPrevPredicate ); - aBinaryPred->SetPredicate2( *aPredIter ); - aCurrPred = aBinaryPred; - } + //======================================================================= + // name : Filter_i::GetPredicate + // Purpose : Get predicate + //======================================================================= + Predicate_ptr Filter_i::GetPredicate() + { + if ( myPredicate == 0 ) + return SMESH::Predicate::_nil(); else - aCurrPred = *aPredIter; - - if ( aCurrBinary != SMESH::FT_LogicalAND ) - aResList.push_back( aCurrPred ); - - aPrevPredicate = aCurrPred; - aPrevBinary = aCurrBinary; - } - - // combine all "OR" operations - - SMESH::Predicate_ptr aResPredicate = SMESH::Predicate::_nil(); - - if ( aResList.size() == 1 ) - aResPredicate = *aResList.begin(); - else if ( aResList.size() > 1 ) - { - std::list::iterator anIter = aResList.begin(); - aResPredicate = *anIter; - anIter++; - for ( ; anIter != aResList.end(); ++anIter ) { - SMESH::LogicalBinary_ptr aBinaryPred = aFilterMgr->CreateLogicalOR(); - aBinaryPred->SetPredicate1( aResPredicate ); - aBinaryPred->SetPredicate2( *anIter ); - aResPredicate = aBinaryPred; + SMESH::Predicate_var anObj = myPredicate->_this(); + // if ( SMESH::Functor_i* fun = SMESH::DownCast( anObj )) + // TPythonDump() << fun << " = " << this << ".GetPredicate()"; + return anObj._retn(); } } - SetPredicate( aResPredicate ); - if ( !aResPredicate->_is_nil() ) - aResPredicate->UnRegister(); + //================================================================================ + /*! + * \brief Find groups it depends on + */ + //================================================================================ - return !aResPredicate->_is_nil(); -} - -//======================================================================= -// name : Filter_i::GetPredicate_i -// Purpose : Get implementation of predicate -//======================================================================= -Predicate_i* Filter_i::GetPredicate_i() -{ - return myPredicate; -} - -//======================================================================= -// name : Filter_i::GetPredicate -// Purpose : Get predicate -//======================================================================= -Predicate_ptr Filter_i::GetPredicate() -{ - if ( myPredicate == 0 ) - return SMESH::Predicate::_nil(); - else + void Filter_i::FindBaseObjects() { - SMESH::Predicate_var anObj = myPredicate->_this(); - // if ( SMESH::Functor_i* fun = SMESH::DownCast( anObj )) - // TPythonDump() << fun << " = " << this << ".GetPredicate()"; - return anObj._retn(); - } -} + // release current groups + for ( size_t i = 0; i < myBaseGroups.size(); ++i ) + if ( myBaseGroups[i] ) + { + myBaseGroups[i]->RemoveModifWaiter( this ); + myBaseGroups[i]->UnRegister(); + } -//================================================================================ -/*! - * \brief Find groups it depends on - */ -//================================================================================ - -void Filter_i::FindBaseObjects() -{ - // release current groups - for ( size_t i = 0; i < myBaseGroups.size(); ++i ) - if ( myBaseGroups[i] ) + // remember new groups + myBaseGroups.clear(); + if ( myPredicate ) { - myBaseGroups[i]->RemoveModifWaiter( this ); - myBaseGroups[i]->UnRegister(); + std::vector predicates; + getPrediacates( myPredicate, predicates ); + for ( size_t i = 0; i < predicates.size(); ++i ) + if ( BelongToMeshGroup_i* bmg = dynamic_cast< BelongToMeshGroup_i* >( predicates[i] )) + { + SMESH::SMESH_GroupBase_var g = bmg->GetGroup(); + SMESH_GroupBase_i* g_i = SMESH::DownCast< SMESH_GroupBase_i*>( g ); + if ( g_i ) + { + g_i->AddModifWaiter( this ); + g_i->Register(); + myBaseGroups.push_back( g_i ); + } + } + } + } + + //================================================================================ + /*! + * \brief When notified on removal of myBaseGroups[i], remove a reference to a + * group from a predicate + */ + //================================================================================ + + void Filter_i::OnBaseObjModified(NotifyerAndWaiter* group, bool removed) + { + if ( !removed ) + return; // a GroupOnFilter holding this filter is notified automatically + + if ( myPredicate ) + { + std::vector predicates; + getPrediacates( myPredicate, predicates ); + for ( size_t i = 0; i < predicates.size(); ++i ) + if ( BelongToMeshGroup_i* bmg = dynamic_cast< BelongToMeshGroup_i* >( predicates[i] )) + { + SMESH::SMESH_GroupBase_var g = bmg->GetGroup(); + SMESH_GroupBase_i* g_i = SMESH::DownCast< SMESH_GroupBase_i*>( g ); + if ( g_i == group ) + { + bmg->SetGroup( SMESH::SMESH_GroupBase::_nil() ); + bmg->SetGroupID( "" ); + } + } } - // remember new groups - myBaseGroups.clear(); - if ( myPredicate ) + FindBaseObjects(); // release and update myBaseGroups; + } + + /* + FILTER LIBRARY + */ + + #define ATTR_TYPE "type" + #define ATTR_COMPARE "compare" + #define ATTR_THRESHOLD "threshold" + #define ATTR_UNARY "unary" + #define ATTR_BINARY "binary" + #define ATTR_THRESHOLD_STR "threshold_str" + #define ATTR_TOLERANCE "tolerance" + #define ATTR_ELEMENT_TYPE "ElementType" + + //======================================================================= + // name : toString + // Purpose : Convert bool to LDOMString + //======================================================================= + static inline LDOMString toString( CORBA::Boolean val ) { - std::vector predicates; - getPrediacates( myPredicate, predicates ); - for ( size_t i = 0; i < predicates.size(); ++i ) - if ( BelongToMeshGroup_i* bmg = dynamic_cast< BelongToMeshGroup_i* >( predicates[i] )) + return val ? "logical not" : ""; + } + + //======================================================================= + // name : toBool + // Purpose : Convert LDOMString to bool + //======================================================================= + static inline bool toBool( const LDOMString& theStr ) + { + return theStr.equals( "logical not" ); + } + + //======================================================================= + // name : toString + // Purpose : Convert double to LDOMString + //======================================================================= + static inline LDOMString toString( CORBA::Double val ) + { + char a[ 255 ]; + sprintf( a, "%e", val ); + return LDOMString( a ); + } + + //======================================================================= + // name : toDouble + // Purpose : Convert LDOMString to double + //======================================================================= + static inline double toDouble( const LDOMString& theStr ) + { + return atof( theStr.GetString() ); + } + + //======================================================================= + // name : toString + // Purpose : Convert functor type to LDOMString + //======================================================================= + static inline LDOMString toString( CORBA::Long theType ) + { + switch ( theType ) + { + case FT_AspectRatio : return "Aspect ratio"; + case FT_Warping : return "Warping"; + case FT_MinimumAngle : return "Minimum angle"; + case FT_Taper : return "Taper"; + case FT_Skew : return "Skew"; + case FT_Area : return "Area"; + case FT_Volume3D : return "Volume3D"; + case FT_MaxElementLength2D : return "Max element length 2D"; + case FT_MaxElementLength3D : return "Max element length 3D"; + case FT_BelongToMeshGroup : return "Belong to Mesh Group"; + case FT_BelongToGeom : return "Belong to Geom"; + case FT_BelongToPlane : return "Belong to Plane"; + case FT_BelongToCylinder : return "Belong to Cylinder"; + case FT_BelongToGenSurface : return "Belong to Generic Surface"; + case FT_LyingOnGeom : return "Lying on Geom"; + case FT_BadOrientedVolume : return "Bad Oriented Volume"; + case FT_BareBorderVolume : return "Volumes with bare border"; + case FT_BareBorderFace : return "Faces with bare border"; + case FT_OverConstrainedVolume : return "Over-constrained Volumes"; + case FT_OverConstrainedFace : return "Over-constrained Faces"; + case FT_RangeOfIds : return "Range of IDs"; + case FT_FreeBorders : return "Free borders"; + case FT_FreeEdges : return "Free edges"; + case FT_FreeFaces : return "Free faces"; + case FT_FreeNodes : return "Free nodes"; + case FT_EqualNodes : return "Equal nodes"; + case FT_EqualEdges : return "Equal edges"; + case FT_EqualFaces : return "Equal faces"; + case FT_EqualVolumes : return "Equal volumes"; + case FT_MultiConnection : return "Borders at multi-connections"; + case FT_MultiConnection2D : return "Borders at multi-connections 2D"; + case FT_Length : return "Length"; + case FT_Length2D : return "Length 2D"; + case FT_Length3D : return "Length 3D"; + case FT_Deflection2D : return "Deflection 2D"; + case FT_LessThan : return "Less than"; + case FT_MoreThan : return "More than"; + case FT_EqualTo : return "Equal to"; + case FT_LogicalNOT : return "Not"; + case FT_LogicalAND : return "And"; + case FT_LogicalOR : return "Or"; + case FT_GroupColor : return "Color of Group"; + case FT_LinearOrQuadratic : return "Linear or Quadratic"; + case FT_ElemGeomType : return "Element geometry type"; + case FT_EntityType : return "Entity type"; + case FT_Undefined : return ""; + default : return ""; + } + } + + //======================================================================= + // name : toFunctorType + // Purpose : Convert LDOMString to functor type + //======================================================================= + static inline SMESH::FunctorType toFunctorType( const LDOMString& theStr ) + { + if ( theStr.equals( "Aspect ratio" ) ) return FT_AspectRatio; + else if ( theStr.equals( "Warping" ) ) return FT_Warping; + else if ( theStr.equals( "Minimum angle" ) ) return FT_MinimumAngle; + else if ( theStr.equals( "Taper" ) ) return FT_Taper; + else if ( theStr.equals( "Skew" ) ) return FT_Skew; + else if ( theStr.equals( "Area" ) ) return FT_Area; + else if ( theStr.equals( "Volume3D" ) ) return FT_Volume3D; + else if ( theStr.equals( "Max element length 2D" ) ) return FT_MaxElementLength2D; + else if ( theStr.equals( "Max element length 3D" ) ) return FT_MaxElementLength3D; + else if ( theStr.equals( "Belong to Mesh Group" ) ) return FT_BelongToMeshGroup; + else if ( theStr.equals( "Belong to Geom" ) ) return FT_BelongToGeom; + else if ( theStr.equals( "Belong to Plane" ) ) return FT_BelongToPlane; + else if ( theStr.equals( "Belong to Cylinder" ) ) return FT_BelongToCylinder; + else if ( theStr.equals( "Belong to Generic Surface" ) ) return FT_BelongToGenSurface; + else if ( theStr.equals( "Lying on Geom" ) ) return FT_LyingOnGeom; + else if ( theStr.equals( "Free borders" ) ) return FT_FreeBorders; + else if ( theStr.equals( "Free edges" ) ) return FT_FreeEdges; + else if ( theStr.equals( "Free faces" ) ) return FT_FreeFaces; + else if ( theStr.equals( "Free nodes" ) ) return FT_FreeNodes; + else if ( theStr.equals( "Equal nodes" ) ) return FT_EqualNodes; + else if ( theStr.equals( "Equal edges" ) ) return FT_EqualEdges; + else if ( theStr.equals( "Equal faces" ) ) return FT_EqualFaces; + else if ( theStr.equals( "Equal volumes" ) ) return FT_EqualVolumes; + else if ( theStr.equals( "Borders at multi-connections" ) ) return FT_MultiConnection; + // else if ( theStr.equals( "Borders at multi-connections 2D" ) ) return FT_MultiConnection2D; + else if ( theStr.equals( "Length" ) ) return FT_Length; + // else if ( theStr.equals( "Length2D" ) ) return FT_Length2D; + // else if ( theStr.equals( "Length3D" ) ) return FT_Length3D; + else if ( theStr.equals( "Deflection" ) ) return FT_Deflection2D; + else if ( theStr.equals( "Range of IDs" ) ) return FT_RangeOfIds; + else if ( theStr.equals( "Bad Oriented Volume" ) ) return FT_BadOrientedVolume; + else if ( theStr.equals( "Volumes with bare border" ) ) return FT_BareBorderVolume; + else if ( theStr.equals( "Faces with bare border" ) ) return FT_BareBorderFace; + else if ( theStr.equals( "Over-constrained Volumes" ) ) return FT_OverConstrainedVolume; + else if ( theStr.equals( "Over-constrained Faces" ) ) return FT_OverConstrainedFace; + else if ( theStr.equals( "Less than" ) ) return FT_LessThan; + else if ( theStr.equals( "More than" ) ) return FT_MoreThan; + else if ( theStr.equals( "Equal to" ) ) return FT_EqualTo; + else if ( theStr.equals( "Not" ) ) return FT_LogicalNOT; + else if ( theStr.equals( "And" ) ) return FT_LogicalAND; + else if ( theStr.equals( "Or" ) ) return FT_LogicalOR; + else if ( theStr.equals( "Color of Group" ) ) return FT_GroupColor; + else if ( theStr.equals( "Linear or Quadratic" ) ) return FT_LinearOrQuadratic; + else if ( theStr.equals( "Element geometry type" ) ) return FT_ElemGeomType; + else if ( theStr.equals( "Entity type" ) ) return FT_EntityType; + else if ( theStr.equals( "" ) ) return FT_Undefined; + else return FT_Undefined; + } + + //======================================================================= + // name : toFunctorType + // Purpose : Convert LDOMString to value of ElementType enumeration + //======================================================================= + static inline SMESH::ElementType toElementType( const LDOMString& theStr ) + { + if ( theStr.equals( "NODE" ) ) return SMESH::NODE; + else if ( theStr.equals( "EDGE" ) ) return SMESH::EDGE; + else if ( theStr.equals( "FACE" ) ) return SMESH::FACE; + else if ( theStr.equals( "VOLUME" ) ) return SMESH::VOLUME; + else return SMESH::ALL; + } + + //======================================================================= + // name : toString + // Purpose : Convert ElementType to string + //======================================================================= + static inline LDOMString toString( const SMESH::ElementType theType ) + { + switch ( theType ) + { + case SMESH::NODE : return "NODE"; + case SMESH::EDGE : return "EDGE"; + case SMESH::FACE : return "FACE"; + case SMESH::VOLUME : return "VOLUME"; + case SMESH::ALL : return "ALL"; + default : return ""; + } + } + + //======================================================================= + // name : findFilter + // Purpose : Find filter in document + //======================================================================= + static LDOM_Element findFilter( const char* theFilterName, + const LDOM_Document& theDoc, + LDOM_Node* theParent = 0 ) + { + LDOM_Element aRootElement = theDoc.getDocumentElement(); + if ( aRootElement.isNull() || !aRootElement.hasChildNodes() ) + return LDOM_Element(); + + for ( LDOM_Node aTypeNode = aRootElement.getFirstChild(); + !aTypeNode.isNull(); aTypeNode = aTypeNode.getNextSibling() ) + { + for ( LDOM_Node aFilter = aTypeNode.getFirstChild(); + !aFilter.isNull(); aFilter = aFilter.getNextSibling() ) { - SMESH::SMESH_GroupBase_var g = bmg->GetGroup(); - SMESH_GroupBase_i* g_i = SMESH::DownCast< SMESH_GroupBase_i*>( g ); - if ( g_i ) + LDOM_Element* anElem = ( LDOM_Element* )&aFilter; + if ( anElem->getTagName().equals( LDOMString( "filter" ) ) && + anElem->getAttribute( "name" ).equals( LDOMString( theFilterName ) ) ) { - g_i->AddModifWaiter( this ); - g_i->Register(); - myBaseGroups.push_back( g_i ); + if ( theParent != 0 ) + *theParent = aTypeNode; + return (LDOM_Element&)aFilter; } } - } -} - -//================================================================================ -/*! - * \brief When notified on removal of myBaseGroups[i], remove a reference to a - * group from a predicate - */ -//================================================================================ - -void Filter_i::OnBaseObjModified(NotifyerAndWaiter* group, bool removed) -{ - if ( !removed ) - return; // a GroupOnFilter holding this filter is notified automatically - - if ( myPredicate ) - { - std::vector predicates; - getPrediacates( myPredicate, predicates ); - for ( size_t i = 0; i < predicates.size(); ++i ) - if ( BelongToMeshGroup_i* bmg = dynamic_cast< BelongToMeshGroup_i* >( predicates[i] )) - { - SMESH::SMESH_GroupBase_var g = bmg->GetGroup(); - SMESH_GroupBase_i* g_i = SMESH::DownCast< SMESH_GroupBase_i*>( g ); - if ( g_i == group ) - { - bmg->SetGroup( SMESH::SMESH_GroupBase::_nil() ); - bmg->SetGroupID( "" ); - } - } - } - - FindBaseObjects(); // release and update myBaseGroups; -} - -/* - FILTER LIBRARY -*/ - -#define ATTR_TYPE "type" -#define ATTR_COMPARE "compare" -#define ATTR_THRESHOLD "threshold" -#define ATTR_UNARY "unary" -#define ATTR_BINARY "binary" -#define ATTR_THRESHOLD_STR "threshold_str" -#define ATTR_TOLERANCE "tolerance" -#define ATTR_ELEMENT_TYPE "ElementType" - -//======================================================================= -// name : toString -// Purpose : Convert bool to LDOMString -//======================================================================= -static inline LDOMString toString( CORBA::Boolean val ) -{ - return val ? "logical not" : ""; -} - -//======================================================================= -// name : toBool -// Purpose : Convert LDOMString to bool -//======================================================================= -static inline bool toBool( const LDOMString& theStr ) -{ - return theStr.equals( "logical not" ); -} - -//======================================================================= -// name : toString -// Purpose : Convert double to LDOMString -//======================================================================= -static inline LDOMString toString( CORBA::Double val ) -{ - char a[ 255 ]; - sprintf( a, "%e", val ); - return LDOMString( a ); -} - -//======================================================================= -// name : toDouble -// Purpose : Convert LDOMString to double -//======================================================================= -static inline double toDouble( const LDOMString& theStr ) -{ - return atof( theStr.GetString() ); -} - -//======================================================================= -// name : toString -// Purpose : Convert functor type to LDOMString -//======================================================================= -static inline LDOMString toString( CORBA::Long theType ) -{ - switch ( theType ) - { - case FT_AspectRatio : return "Aspect ratio"; - case FT_Warping : return "Warping"; - case FT_MinimumAngle : return "Minimum angle"; - case FT_Taper : return "Taper"; - case FT_Skew : return "Skew"; - case FT_Area : return "Area"; - case FT_Volume3D : return "Volume3D"; - case FT_MaxElementLength2D : return "Max element length 2D"; - case FT_MaxElementLength3D : return "Max element length 3D"; - case FT_BelongToMeshGroup : return "Belong to Mesh Group"; - case FT_BelongToGeom : return "Belong to Geom"; - case FT_BelongToPlane : return "Belong to Plane"; - case FT_BelongToCylinder : return "Belong to Cylinder"; - case FT_BelongToGenSurface : return "Belong to Generic Surface"; - case FT_LyingOnGeom : return "Lying on Geom"; - case FT_BadOrientedVolume : return "Bad Oriented Volume"; - case FT_BareBorderVolume : return "Volumes with bare border"; - case FT_BareBorderFace : return "Faces with bare border"; - case FT_OverConstrainedVolume : return "Over-constrained Volumes"; - case FT_OverConstrainedFace : return "Over-constrained Faces"; - case FT_RangeOfIds : return "Range of IDs"; - case FT_FreeBorders : return "Free borders"; - case FT_FreeEdges : return "Free edges"; - case FT_FreeFaces : return "Free faces"; - case FT_FreeNodes : return "Free nodes"; - case FT_EqualNodes : return "Equal nodes"; - case FT_EqualEdges : return "Equal edges"; - case FT_EqualFaces : return "Equal faces"; - case FT_EqualVolumes : return "Equal volumes"; - case FT_MultiConnection : return "Borders at multi-connections"; - case FT_MultiConnection2D : return "Borders at multi-connections 2D"; - case FT_Length : return "Length"; - case FT_Length2D : return "Length 2D"; - case FT_Length3D : return "Length 3D"; - case FT_Deflection2D : return "Deflection 2D"; - case FT_LessThan : return "Less than"; - case FT_MoreThan : return "More than"; - case FT_EqualTo : return "Equal to"; - case FT_LogicalNOT : return "Not"; - case FT_LogicalAND : return "And"; - case FT_LogicalOR : return "Or"; - case FT_GroupColor : return "Color of Group"; - case FT_LinearOrQuadratic : return "Linear or Quadratic"; - case FT_ElemGeomType : return "Element geometry type"; - case FT_EntityType : return "Entity type"; - case FT_Undefined : return ""; - default : return ""; - } -} - -//======================================================================= -// name : toFunctorType -// Purpose : Convert LDOMString to functor type -//======================================================================= -static inline SMESH::FunctorType toFunctorType( const LDOMString& theStr ) -{ - if ( theStr.equals( "Aspect ratio" ) ) return FT_AspectRatio; - else if ( theStr.equals( "Warping" ) ) return FT_Warping; - else if ( theStr.equals( "Minimum angle" ) ) return FT_MinimumAngle; - else if ( theStr.equals( "Taper" ) ) return FT_Taper; - else if ( theStr.equals( "Skew" ) ) return FT_Skew; - else if ( theStr.equals( "Area" ) ) return FT_Area; - else if ( theStr.equals( "Volume3D" ) ) return FT_Volume3D; - else if ( theStr.equals( "Max element length 2D" ) ) return FT_MaxElementLength2D; - else if ( theStr.equals( "Max element length 3D" ) ) return FT_MaxElementLength3D; - else if ( theStr.equals( "Belong to Mesh Group" ) ) return FT_BelongToMeshGroup; - else if ( theStr.equals( "Belong to Geom" ) ) return FT_BelongToGeom; - else if ( theStr.equals( "Belong to Plane" ) ) return FT_BelongToPlane; - else if ( theStr.equals( "Belong to Cylinder" ) ) return FT_BelongToCylinder; - else if ( theStr.equals( "Belong to Generic Surface" ) ) return FT_BelongToGenSurface; - else if ( theStr.equals( "Lying on Geom" ) ) return FT_LyingOnGeom; - else if ( theStr.equals( "Free borders" ) ) return FT_FreeBorders; - else if ( theStr.equals( "Free edges" ) ) return FT_FreeEdges; - else if ( theStr.equals( "Free faces" ) ) return FT_FreeFaces; - else if ( theStr.equals( "Free nodes" ) ) return FT_FreeNodes; - else if ( theStr.equals( "Equal nodes" ) ) return FT_EqualNodes; - else if ( theStr.equals( "Equal edges" ) ) return FT_EqualEdges; - else if ( theStr.equals( "Equal faces" ) ) return FT_EqualFaces; - else if ( theStr.equals( "Equal volumes" ) ) return FT_EqualVolumes; - else if ( theStr.equals( "Borders at multi-connections" ) ) return FT_MultiConnection; - // else if ( theStr.equals( "Borders at multi-connections 2D" ) ) return FT_MultiConnection2D; - else if ( theStr.equals( "Length" ) ) return FT_Length; - // else if ( theStr.equals( "Length2D" ) ) return FT_Length2D; - // else if ( theStr.equals( "Length3D" ) ) return FT_Length3D; - else if ( theStr.equals( "Deflection" ) ) return FT_Deflection2D; - else if ( theStr.equals( "Range of IDs" ) ) return FT_RangeOfIds; - else if ( theStr.equals( "Bad Oriented Volume" ) ) return FT_BadOrientedVolume; - else if ( theStr.equals( "Volumes with bare border" ) ) return FT_BareBorderVolume; - else if ( theStr.equals( "Faces with bare border" ) ) return FT_BareBorderFace; - else if ( theStr.equals( "Over-constrained Volumes" ) ) return FT_OverConstrainedVolume; - else if ( theStr.equals( "Over-constrained Faces" ) ) return FT_OverConstrainedFace; - else if ( theStr.equals( "Less than" ) ) return FT_LessThan; - else if ( theStr.equals( "More than" ) ) return FT_MoreThan; - else if ( theStr.equals( "Equal to" ) ) return FT_EqualTo; - else if ( theStr.equals( "Not" ) ) return FT_LogicalNOT; - else if ( theStr.equals( "And" ) ) return FT_LogicalAND; - else if ( theStr.equals( "Or" ) ) return FT_LogicalOR; - else if ( theStr.equals( "Color of Group" ) ) return FT_GroupColor; - else if ( theStr.equals( "Linear or Quadratic" ) ) return FT_LinearOrQuadratic; - else if ( theStr.equals( "Element geometry type" ) ) return FT_ElemGeomType; - else if ( theStr.equals( "Entity type" ) ) return FT_EntityType; - else if ( theStr.equals( "" ) ) return FT_Undefined; - else return FT_Undefined; -} - -//======================================================================= -// name : toFunctorType -// Purpose : Convert LDOMString to value of ElementType enumeration -//======================================================================= -static inline SMESH::ElementType toElementType( const LDOMString& theStr ) -{ - if ( theStr.equals( "NODE" ) ) return SMESH::NODE; - else if ( theStr.equals( "EDGE" ) ) return SMESH::EDGE; - else if ( theStr.equals( "FACE" ) ) return SMESH::FACE; - else if ( theStr.equals( "VOLUME" ) ) return SMESH::VOLUME; - else return SMESH::ALL; -} - -//======================================================================= -// name : toString -// Purpose : Convert ElementType to string -//======================================================================= -static inline LDOMString toString( const SMESH::ElementType theType ) -{ - switch ( theType ) - { - case SMESH::NODE : return "NODE"; - case SMESH::EDGE : return "EDGE"; - case SMESH::FACE : return "FACE"; - case SMESH::VOLUME : return "VOLUME"; - case SMESH::ALL : return "ALL"; - default : return ""; - } -} - -//======================================================================= -// name : findFilter -// Purpose : Find filter in document -//======================================================================= -static LDOM_Element findFilter( const char* theFilterName, - const LDOM_Document& theDoc, - LDOM_Node* theParent = 0 ) -{ - LDOM_Element aRootElement = theDoc.getDocumentElement(); - if ( aRootElement.isNull() || !aRootElement.hasChildNodes() ) + } return LDOM_Element(); - - for ( LDOM_Node aTypeNode = aRootElement.getFirstChild(); - !aTypeNode.isNull(); aTypeNode = aTypeNode.getNextSibling() ) - { - for ( LDOM_Node aFilter = aTypeNode.getFirstChild(); - !aFilter.isNull(); aFilter = aFilter.getNextSibling() ) - { - LDOM_Element* anElem = ( LDOM_Element* )&aFilter; - if ( anElem->getTagName().equals( LDOMString( "filter" ) ) && - anElem->getAttribute( "name" ).equals( LDOMString( theFilterName ) ) ) - { - if ( theParent != 0 ) - *theParent = aTypeNode; - return (LDOM_Element&)aFilter; - } - } } - return LDOM_Element(); -} -//======================================================================= -// name : getSectionName -// Purpose : Get name of section of filters -//======================================================================= -static const char* getSectionName( const ElementType theType ) -{ - switch ( theType ) + //======================================================================= + // name : getSectionName + // Purpose : Get name of section of filters + //======================================================================= + static const char* getSectionName( const ElementType theType ) { - case SMESH::NODE : return "Filters for nodes"; - case SMESH::EDGE : return "Filters for edges"; - case SMESH::FACE : return "Filters for faces"; - case SMESH::VOLUME : return "Filters for volumes"; - case SMESH::ALL : return "Filters for elements"; - default : return ""; - } -} - -//======================================================================= -// name : getSection -// Purpose : Create section for filters corresponding to the entity type -//======================================================================= -static LDOM_Node getSection( const ElementType theType, - LDOM_Document& theDoc, - const bool toCreate = false ) -{ - LDOM_Element aRootElement = theDoc.getDocumentElement(); - if ( aRootElement.isNull() ) - return LDOM_Node(); - - // Find section - bool anExist = false; - const char* aSectionName = getSectionName( theType ); - if ( strcmp( aSectionName, "" ) == 0 ) - return LDOM_Node(); - - LDOM_NodeList aSections = theDoc.getElementsByTagName( "section" ); - LDOM_Node aNode; - for ( int i = 0, n = aSections.getLength(); i < n; i++ ) - { - aNode = aSections.item( i ); - LDOM_Element& anItem = ( LDOM_Element& )aNode; - if ( anItem.getAttribute( "name" ).equals( LDOMString( aSectionName ) ) ) + switch ( theType ) { - anExist = true; - break; + case SMESH::NODE : return "Filters for nodes"; + case SMESH::EDGE : return "Filters for edges"; + case SMESH::FACE : return "Filters for faces"; + case SMESH::VOLUME : return "Filters for volumes"; + case SMESH::ALL : return "Filters for elements"; + default : return ""; } } - // Create new section if necessary - if ( !anExist ) + //======================================================================= + // name : getSection + // Purpose : Create section for filters corresponding to the entity type + //======================================================================= + static LDOM_Node getSection( const ElementType theType, + LDOM_Document& theDoc, + const bool toCreate = false ) { - if ( toCreate ) - { - LDOM_Element aNewItem = theDoc.createElement( "section" ); - aNewItem.setAttribute( "name", aSectionName ); - aRootElement.appendChild( aNewItem ); - return aNewItem; - } - else + LDOM_Element aRootElement = theDoc.getDocumentElement(); + if ( aRootElement.isNull() ) return LDOM_Node(); + + // Find section + bool anExist = false; + const char* aSectionName = getSectionName( theType ); + if ( strcmp( aSectionName, "" ) == 0 ) + return LDOM_Node(); + + LDOM_NodeList aSections = theDoc.getElementsByTagName( "section" ); + LDOM_Node aNode; + for ( int i = 0, n = aSections.getLength(); i < n; i++ ) + { + aNode = aSections.item( i ); + LDOM_Element& anItem = ( LDOM_Element& )aNode; + if ( anItem.getAttribute( "name" ).equals( LDOMString( aSectionName ) ) ) + { + anExist = true; + break; + } + } + + // Create new section if necessary + if ( !anExist ) + { + if ( toCreate ) + { + LDOM_Element aNewItem = theDoc.createElement( "section" ); + aNewItem.setAttribute( "name", aSectionName ); + aRootElement.appendChild( aNewItem ); + return aNewItem; + } + else + return LDOM_Node(); + } + return + aNode; } - return - aNode; -} -//======================================================================= -// name : createFilterItem -// Purpose : Create filter item or LDOM document -//======================================================================= -static LDOM_Element createFilterItem( const char* theName, - SMESH::Filter_ptr theFilter, - LDOM_Document& theDoc ) -{ - // create new filter in document - LDOM_Element aFilterItem = theDoc.createElement( "filter" ); - aFilterItem.setAttribute( "name", theName ); - - // save filter criterions - SMESH::Filter::Criteria_var aCriteria = new SMESH::Filter::Criteria; - - if ( !theFilter->GetCriteria( aCriteria ) ) - return LDOM_Element(); - - for ( CORBA::ULong i = 0, n = aCriteria->length(); i < n; i++ ) + //======================================================================= + // name : createFilterItem + // Purpose : Create filter item or LDOM document + //======================================================================= + static LDOM_Element createFilterItem( const char* theName, + SMESH::Filter_ptr theFilter, + LDOM_Document& theDoc ) { - LDOM_Element aCriterionItem = theDoc.createElement( "criterion" ); + // create new filter in document + LDOM_Element aFilterItem = theDoc.createElement( "filter" ); + aFilterItem.setAttribute( "name", theName ); + + // save filter criterions + SMESH::Filter::Criteria_var aCriteria = new SMESH::Filter::Criteria; + + if ( !theFilter->GetCriteria( aCriteria ) ) + return LDOM_Element(); + + for ( CORBA::ULong i = 0, n = aCriteria->length(); i < n; i++ ) + { + LDOM_Element aCriterionItem = theDoc.createElement( "criterion" ); - aCriterionItem.setAttribute( ATTR_TYPE , toString( aCriteria[ i ].Type) ); - aCriterionItem.setAttribute( ATTR_COMPARE , toString( aCriteria[ i ].Compare ) ); - aCriterionItem.setAttribute( ATTR_THRESHOLD , toString( aCriteria[ i ].Threshold ) ); - aCriterionItem.setAttribute( ATTR_UNARY , toString( aCriteria[ i ].UnaryOp ) ); - aCriterionItem.setAttribute( ATTR_BINARY , toString( aCriteria[ i ].BinaryOp ) ); + aCriterionItem.setAttribute( ATTR_TYPE , toString( aCriteria[ i ].Type) ); + aCriterionItem.setAttribute( ATTR_COMPARE , toString( aCriteria[ i ].Compare ) ); + aCriterionItem.setAttribute( ATTR_THRESHOLD , toString( aCriteria[ i ].Threshold ) ); + aCriterionItem.setAttribute( ATTR_UNARY , toString( aCriteria[ i ].UnaryOp ) ); + aCriterionItem.setAttribute( ATTR_BINARY , toString( aCriteria[ i ].BinaryOp ) ); - aCriterionItem.setAttribute( ATTR_THRESHOLD_STR, (const char*)aCriteria[ i ].ThresholdStr ); - aCriterionItem.setAttribute( ATTR_TOLERANCE , toString( aCriteria[ i ].Tolerance ) ); - aCriterionItem.setAttribute( ATTR_ELEMENT_TYPE , - toString( (SMESH::ElementType)aCriteria[ i ].TypeOfElement ) ); + aCriterionItem.setAttribute( ATTR_THRESHOLD_STR, (const char*)aCriteria[ i ].ThresholdStr ); + aCriterionItem.setAttribute( ATTR_TOLERANCE , toString( aCriteria[ i ].Tolerance ) ); + aCriterionItem.setAttribute( ATTR_ELEMENT_TYPE , + toString( (SMESH::ElementType)aCriteria[ i ].TypeOfElement ) ); - aFilterItem.appendChild( aCriterionItem ); - } - - return aFilterItem; -} - -//======================================================================= -// name : FilterLibrary_i::FilterLibrary_i -// Purpose : Constructor -//======================================================================= -FilterLibrary_i::FilterLibrary_i( const char* theFileName ) -{ - myFileName = CORBA::string_dup( theFileName ); - SMESH::FilterManager_i* aFilterMgr = new SMESH::FilterManager_i(); - myFilterMgr = aFilterMgr->_this(); - - LDOMParser aParser; - - // Try to use existing library file - bool anExists = false; - if ( !aParser.parse( myFileName ) ) - { - myDoc = aParser.getDocument(); - anExists = true; - } - // Create a new XML document if it doesn't exist - else - myDoc = LDOM_Document::createDocument( LDOMString() ); - - LDOM_Element aRootElement = myDoc.getDocumentElement(); - if ( aRootElement.isNull() ) - { - // If the existing document is empty --> try to create a new one - if ( anExists ) - myDoc = LDOM_Document::createDocument( LDOMString() ); - } -} - -//======================================================================= -// name : FilterLibrary_i::FilterLibrary_i -// Purpose : Constructor -//======================================================================= -FilterLibrary_i::FilterLibrary_i() -{ - myFileName = 0; - SMESH::FilterManager_i* aFilter = new SMESH::FilterManager_i(); - myFilterMgr = aFilter->_this(); - - myDoc = LDOM_Document::createDocument( LDOMString() ); -} - -FilterLibrary_i::~FilterLibrary_i() -{ - CORBA::string_free( myFileName ); - //TPythonDump()< aCriteria; - - for ( LDOM_Node aCritNode = aFilter.getFirstChild(); - !aCritNode.isNull() ; aCritNode = aCritNode.getNextSibling() ) - { - LDOM_Element* aCrit = (LDOM_Element*)&aCritNode; - - const char* aTypeStr = aCrit->getAttribute( ATTR_TYPE ).GetString(); - const char* aCompareStr = aCrit->getAttribute( ATTR_COMPARE ).GetString(); - const char* aUnaryStr = aCrit->getAttribute( ATTR_UNARY ).GetString(); - const char* aBinaryStr = aCrit->getAttribute( ATTR_BINARY ).GetString(); - const char* anElemTypeStr = aCrit->getAttribute( ATTR_ELEMENT_TYPE ).GetString(); - - SMESH::Filter::Criterion aCriterion = createCriterion(); - - aCriterion.Type = toFunctorType( aTypeStr ); - aCriterion.Compare = toFunctorType( aCompareStr ); - aCriterion.UnaryOp = toFunctorType( aUnaryStr ); - aCriterion.BinaryOp = toFunctorType( aBinaryStr ); - - aCriterion.TypeOfElement = toElementType( anElemTypeStr ); - - LDOMString str = aCrit->getAttribute( ATTR_THRESHOLD ); - int val = 0; - aCriterion.Threshold = str.Type() == LDOMBasicString::LDOM_Integer && str.GetInteger( val ) - ? val : atof( str.GetString() ); - - str = aCrit->getAttribute( ATTR_TOLERANCE ); - aCriterion.Tolerance = str.Type() == LDOMBasicString::LDOM_Integer && str.GetInteger( val ) - ? val : atof( str.GetString() ); - - str = aCrit->getAttribute( ATTR_THRESHOLD_STR ); - if ( str.Type() == LDOMBasicString::LDOM_Integer && str.GetInteger( val ) ) - { - char a[ 255 ]; - sprintf( a, "%d", val ); - aCriterion.ThresholdStr = CORBA::string_dup( a ); + aFilterItem.appendChild( aCriterionItem ); } + + return aFilterItem; + } + + //======================================================================= + // name : FilterLibrary_i::FilterLibrary_i + // Purpose : Constructor + //======================================================================= + FilterLibrary_i::FilterLibrary_i( const char* theFileName ) + { + myFileName = CORBA::string_dup( theFileName ); + SMESH::FilterManager_i* aFilterMgr = new SMESH::FilterManager_i(); + myFilterMgr = aFilterMgr->_this(); + + LDOMParser aParser; + + // Try to use existing library file + bool anExists = false; + if ( !aParser.parse( myFileName ) ) + { + myDoc = aParser.getDocument(); + anExists = true; + } + // Create a new XML document if it doesn't exist else - aCriterion.ThresholdStr = str.GetString(); + myDoc = LDOM_Document::createDocument( LDOMString() ); - aCriteria.push_back( aCriterion ); - } - - SMESH::Filter::Criteria_var aCriteriaVar = new SMESH::Filter::Criteria; - aCriteriaVar->length( aCriteria.size() ); - - CORBA::ULong i = 0; - std::list::iterator anIter = aCriteria.begin(); - - for( ; anIter != aCriteria.end(); ++anIter ) - aCriteriaVar[ i++ ] = *anIter; - - aRes = myFilterMgr->CreateFilter(); - aRes->SetCriteria( aCriteriaVar.inout() ); - - TPythonDump()<_is_nil() ) - return false; - - // get section corresponding to the filter type - ElementType anEntType = theFilter->GetElementType(); - - LDOM_Node aSection = getSection( anEntType, myDoc, true ); - if ( aSection.isNull() ) - return false; - - // create filter item - LDOM_Element aFilterItem = createFilterItem( theFilterName, theFilter, myDoc ); - if ( aFilterItem.isNull() ) - return false; - else - { - aSection.appendChild( aFilterItem ); - if(Filter_i* aFilter = DownCast(theFilter)) - TPythonDump()<CreateFilter(); - - LDOM_Element aFilterItem = createFilterItem( theFilterName, aFilter, myDoc ); - if ( aFilterItem.isNull() ) - return false; - else - { - aSection.appendChild( aFilterItem ); - TPythonDump()<_is_nil() ) - return false; - - LDOM_Element aNewItem = createFilterItem( theNewName, theFilter, myDoc ); - if ( aNewItem.isNull() ) - return false; - else - { - aFilterItem.ReplaceElement( aNewItem ); - if(Filter_i* aFilter = DownCast(theFilter)) - TPythonDump()<length(); -} - -//======================================================================= -// name : FilterLibrary_i::GetNames -// Purpose : Get names of filters from library -//======================================================================= -string_array* FilterLibrary_i::GetNames( ElementType theType ) -{ - string_array_var anArray = new string_array; - TColStd_SequenceOfHAsciiString aSeq; - - LDOM_Node aSection = getSection( theType, myDoc, false ); - - if ( !aSection.isNull() ) - { - for ( LDOM_Node aFilter = aSection.getFirstChild(); - !aFilter.isNull(); aFilter = aFilter.getNextSibling() ) + LDOM_Element aRootElement = myDoc.getDocumentElement(); + if ( aRootElement.isNull() ) { - LDOM_Element& anElem = ( LDOM_Element& )aFilter; - aSeq.Append( new TCollection_HAsciiString( - (Standard_CString)anElem.getAttribute( "name" ).GetString() ) ); + // If the existing document is empty --> try to create a new one + if ( anExists ) + myDoc = LDOM_Document::createDocument( LDOMString() ); } } - anArray->length( aSeq.Length() ); - for ( int i = 1, n = aSeq.Length(); i <= n; i++ ) - anArray[ i - 1 ] = CORBA::string_dup( aSeq( i )->ToCString() ); - - return anArray._retn(); -} - -//======================================================================= -// name : FilterLibrary_i::GetAllNames -// Purpose : Get names of filters from library -//======================================================================= -string_array* FilterLibrary_i::GetAllNames() -{ - string_array_var aResArray = new string_array; - for ( int type = SMESH::ALL; type <= SMESH::VOLUME; type++ ) + //======================================================================= + // name : FilterLibrary_i::FilterLibrary_i + // Purpose : Constructor + //======================================================================= + FilterLibrary_i::FilterLibrary_i() { - SMESH::string_array_var aNames = GetNames( (SMESH::ElementType)type ); + myFileName = 0; + SMESH::FilterManager_i* aFilter = new SMESH::FilterManager_i(); + myFilterMgr = aFilter->_this(); - int aPrevLength = aResArray->length(); - aResArray->length( aPrevLength + aNames->length() ); - for ( int i = 0, n = aNames->length(); i < n; i++ ) - aResArray[ aPrevLength + i ] = aNames[ i ]; + myDoc = LDOM_Document::createDocument( LDOMString() ); } - return aResArray._retn(); -} - -//================================================================================ -/*! - * \brief Return an array of strings corresponding to items of enum FunctorType - */ -//================================================================================ - -static const char** getFunctNames() -{ - static const char* functName[] = { - // IT's necessary to update this array according to enum FunctorType (SMESH_Filter.idl) - // The order is IMPORTANT !!! - "FT_AspectRatio", - "FT_AspectRatio3D", - "FT_Warping", - "FT_MinimumAngle", - "FT_Taper", - "FT_Skew", - "FT_Area", - "FT_Volume3D", - "FT_MaxElementLength2D", - "FT_MaxElementLength3D", - "FT_FreeBorders", - "FT_FreeEdges", - "FT_FreeNodes", - "FT_FreeFaces", - "FT_EqualNodes", - "FT_EqualEdges", - "FT_EqualFaces", - "FT_EqualVolumes", - "FT_MultiConnection", - "FT_MultiConnection2D", - "FT_Length", - "FT_Length2D", - "FT_Length3D", - "FT_Deflection2D", - "FT_NodeConnectivityNumber", - "FT_BelongToMeshGroup", - "FT_BelongToGeom", - "FT_BelongToPlane", - "FT_BelongToCylinder", - "FT_BelongToGenSurface", - "FT_LyingOnGeom", - "FT_RangeOfIds", - "FT_BadOrientedVolume", - "FT_BareBorderVolume", - "FT_BareBorderFace", - "FT_OverConstrainedVolume", - "FT_OverConstrainedFace", - "FT_LinearOrQuadratic", - "FT_GroupColor", - "FT_ElemGeomType", - "FT_EntityType", - "FT_CoplanarFaces", - "FT_BallDiameter", - "FT_ConnectedElements", - "FT_LessThan", - "FT_MoreThan", - "FT_EqualTo", - "FT_LogicalNOT", - "FT_LogicalAND", - "FT_LogicalOR", - "FT_Undefined"}; - -#ifdef _DEBUG_ - // check if functName is complete, compilation failure means that enum FunctorType changed - const int nbFunctors = sizeof(functName) / sizeof(const char*); - int _assert[( nbFunctors == SMESH::FT_Undefined + 1 ) ? 2 : -1 ]; _assert[0]=_assert[1]=0; -#endif - - return functName; -} - -//================================================================================ -/*! - * \brief Return a string corresponding to an item of enum FunctorType - */ -//================================================================================ - -const char* SMESH::FunctorTypeToString(SMESH::FunctorType ft) -{ - if ( ft < 0 || ft > SMESH::FT_Undefined ) - return "FT_Undefined"; - return getFunctNames()[ ft ]; -} - -//================================================================================ -/*! - * \brief Converts a string to FunctorType. This is reverse of FunctorTypeToString() - */ -//================================================================================ - -SMESH::FunctorType SMESH::StringToFunctorType(const char* str) -{ - std::string name( str + 3 ); // skip "FT_" - const char** functNames = getFunctNames(); - int ft = 0; - for ( ; ft < SMESH::FT_Undefined; ++ft ) - if ( name == ( functNames[ft] + 3 )) - break; - - //ASSERT( strcmp( str, FunctorTypeToString( SMESH::FunctorType( ft ))) == 0 ); - - return SMESH::FunctorType( ft ); -} - -//================================================================================ -/*! - * \brief calls OnBaseObjModified(), if who != this, and myWaiters[i]->Modified(who) - */ -//================================================================================ - -void NotifyerAndWaiter::Modified( bool removed, NotifyerAndWaiter* who ) -{ - if ( who != 0 && who != this ) - OnBaseObjModified( who, removed ); - else - who = this; - - std::list waiters = myWaiters; // myWaiters can be changed by Modified() - std::list::iterator i = waiters.begin(); - for ( ; i != waiters.end(); ++i ) - (*i)->Modified( removed, who ); -} - -//================================================================================ -/*! - * \brief Stores an object to be notified on change of predicate - */ -//================================================================================ - -void NotifyerAndWaiter::AddModifWaiter( NotifyerAndWaiter* waiter ) -{ - if ( waiter ) - myWaiters.push_back( waiter ); -} - -//================================================================================ -/*! - * \brief Removes an object to be notified on change of predicate - */ -//================================================================================ - -void NotifyerAndWaiter::RemoveModifWaiter( NotifyerAndWaiter* waiter ) -{ - myWaiters.remove( waiter ); -} - -//================================================================================ -/*! - * \brief Checks if a waiter is among myWaiters, maybe nested - */ -//================================================================================ - -bool NotifyerAndWaiter::ContainModifWaiter( NotifyerAndWaiter* waiter ) -{ - bool is = ( waiter == this ); - - std::list::iterator w = myWaiters.begin(); - for ( ; !is && w != myWaiters.end(); ++w ) - is = (*w)->ContainModifWaiter( waiter ); - - return is; + FilterLibrary_i::~FilterLibrary_i() + { + CORBA::string_free( myFileName ); + //TPythonDump()< aCriteria; + + for ( LDOM_Node aCritNode = aFilter.getFirstChild(); + !aCritNode.isNull() ; aCritNode = aCritNode.getNextSibling() ) + { + LDOM_Element* aCrit = (LDOM_Element*)&aCritNode; + + const char* aTypeStr = aCrit->getAttribute( ATTR_TYPE ).GetString(); + const char* aCompareStr = aCrit->getAttribute( ATTR_COMPARE ).GetString(); + const char* aUnaryStr = aCrit->getAttribute( ATTR_UNARY ).GetString(); + const char* aBinaryStr = aCrit->getAttribute( ATTR_BINARY ).GetString(); + const char* anElemTypeStr = aCrit->getAttribute( ATTR_ELEMENT_TYPE ).GetString(); + + SMESH::Filter::Criterion aCriterion = createCriterion(); + + aCriterion.Type = toFunctorType( aTypeStr ); + aCriterion.Compare = toFunctorType( aCompareStr ); + aCriterion.UnaryOp = toFunctorType( aUnaryStr ); + aCriterion.BinaryOp = toFunctorType( aBinaryStr ); + + aCriterion.TypeOfElement = toElementType( anElemTypeStr ); + + LDOMString str = aCrit->getAttribute( ATTR_THRESHOLD ); + int val = 0; + aCriterion.Threshold = str.Type() == LDOMBasicString::LDOM_Integer && str.GetInteger( val ) + ? val : atof( str.GetString() ); + + str = aCrit->getAttribute( ATTR_TOLERANCE ); + aCriterion.Tolerance = str.Type() == LDOMBasicString::LDOM_Integer && str.GetInteger( val ) + ? val : atof( str.GetString() ); + + str = aCrit->getAttribute( ATTR_THRESHOLD_STR ); + if ( str.Type() == LDOMBasicString::LDOM_Integer && str.GetInteger( val ) ) + { + char a[ 255 ]; + sprintf( a, "%d", val ); + aCriterion.ThresholdStr = CORBA::string_dup( a ); + } + else + aCriterion.ThresholdStr = str.GetString(); + + aCriteria.push_back( aCriterion ); + } + + SMESH::Filter::Criteria_var aCriteriaVar = new SMESH::Filter::Criteria; + aCriteriaVar->length( aCriteria.size() ); + + CORBA::ULong i = 0; + std::list::iterator anIter = aCriteria.begin(); + + for( ; anIter != aCriteria.end(); ++anIter ) + aCriteriaVar[ i++ ] = *anIter; + + aRes = myFilterMgr->CreateFilter(); + aRes->SetCriteria( aCriteriaVar.inout() ); + + TPythonDump()<_is_nil() ) + return false; + + // get section corresponding to the filter type + ElementType anEntType = theFilter->GetElementType(); + + LDOM_Node aSection = getSection( anEntType, myDoc, true ); + if ( aSection.isNull() ) + return false; + + // create filter item + LDOM_Element aFilterItem = createFilterItem( theFilterName, theFilter, myDoc ); + if ( aFilterItem.isNull() ) + return false; + else + { + aSection.appendChild( aFilterItem ); + if(Filter_i* aFilter = DownCast(theFilter)) + TPythonDump()<CreateFilter(); + + LDOM_Element aFilterItem = createFilterItem( theFilterName, aFilter, myDoc ); + if ( aFilterItem.isNull() ) + return false; + else + { + aSection.appendChild( aFilterItem ); + TPythonDump()<_is_nil() ) + return false; + + LDOM_Element aNewItem = createFilterItem( theNewName, theFilter, myDoc ); + if ( aNewItem.isNull() ) + return false; + else + { + aFilterItem.ReplaceElement( aNewItem ); + if(Filter_i* aFilter = DownCast(theFilter)) + TPythonDump()<length(); + } + + //======================================================================= + // name : FilterLibrary_i::GetNames + // Purpose : Get names of filters from library + //======================================================================= + string_array* FilterLibrary_i::GetNames( ElementType theType ) + { + string_array_var anArray = new string_array; + TColStd_SequenceOfHAsciiString aSeq; + + LDOM_Node aSection = getSection( theType, myDoc, false ); + + if ( !aSection.isNull() ) + { + for ( LDOM_Node aFilter = aSection.getFirstChild(); + !aFilter.isNull(); aFilter = aFilter.getNextSibling() ) + { + LDOM_Element& anElem = ( LDOM_Element& )aFilter; + aSeq.Append( new TCollection_HAsciiString( + (Standard_CString)anElem.getAttribute( "name" ).GetString() ) ); + } + } + + anArray->length( aSeq.Length() ); + for ( int i = 1, n = aSeq.Length(); i <= n; i++ ) + anArray[ i - 1 ] = CORBA::string_dup( aSeq( i )->ToCString() ); + + return anArray._retn(); + } + + //======================================================================= + // name : FilterLibrary_i::GetAllNames + // Purpose : Get names of filters from library + //======================================================================= + string_array* FilterLibrary_i::GetAllNames() + { + string_array_var aResArray = new string_array; + for ( int type = SMESH::ALL; type <= SMESH::VOLUME; type++ ) + { + SMESH::string_array_var aNames = GetNames( (SMESH::ElementType)type ); + + int aPrevLength = aResArray->length(); + aResArray->length( aPrevLength + aNames->length() ); + for ( int i = 0, n = aNames->length(); i < n; i++ ) + aResArray[ aPrevLength + i ] = aNames[ i ]; + } + + return aResArray._retn(); + } + + //================================================================================ + /*! + * \brief Return an array of strings corresponding to items of enum FunctorType + */ + //================================================================================ + + static const char** getFunctNames() + { + static const char* functName[] = { + // IT's necessary to update this array according to enum FunctorType (SMESH_Filter.idl) + // The order is IMPORTANT !!! + "FT_AspectRatio", + "FT_AspectRatio3D", + "FT_Warping", + "FT_MinimumAngle", + "FT_Taper", + "FT_Skew", + "FT_Area", + "FT_Volume3D", + "FT_MaxElementLength2D", + "FT_MaxElementLength3D", + "FT_FreeBorders", + "FT_FreeEdges", + "FT_FreeNodes", + "FT_FreeFaces", + "FT_EqualNodes", + "FT_EqualEdges", + "FT_EqualFaces", + "FT_EqualVolumes", + "FT_MultiConnection", + "FT_MultiConnection2D", + "FT_Length", + "FT_Length2D", + "FT_Length3D", + "FT_Deflection2D", + "FT_NodeConnectivityNumber", + "FT_BelongToMeshGroup", + "FT_BelongToGeom", + "FT_BelongToPlane", + "FT_BelongToCylinder", + "FT_BelongToGenSurface", + "FT_LyingOnGeom", + "FT_RangeOfIds", + "FT_BadOrientedVolume", + "FT_BareBorderVolume", + "FT_BareBorderFace", + "FT_OverConstrainedVolume", + "FT_OverConstrainedFace", + "FT_LinearOrQuadratic", + "FT_GroupColor", + "FT_ElemGeomType", + "FT_EntityType", + "FT_CoplanarFaces", + "FT_BallDiameter", + "FT_ConnectedElements", + "FT_LessThan", + "FT_MoreThan", + "FT_EqualTo", + "FT_LogicalNOT", + "FT_LogicalAND", + "FT_LogicalOR", + "FT_Undefined"}; + + // check if functName is complete, compilation failure means that enum FunctorType changed + static_assert( sizeof(functName) / sizeof(const char*) == SMESH::FT_Undefined + 1, + "Update names of FunctorType's!!!" ); + + return functName; + } + + //================================================================================ + /*! + * \brief Return a string corresponding to an item of enum FunctorType + */ + //================================================================================ + + const char* FunctorTypeToString(FunctorType ft) + { + if ( ft < 0 || ft > SMESH::FT_Undefined ) + return "FT_Undefined"; + return getFunctNames()[ ft ]; + } + + //================================================================================ + /*! + * \brief Converts a string to FunctorType. This is reverse of FunctorTypeToString() + */ + //================================================================================ + + FunctorType StringToFunctorType(const char* str) + { + std::string name( str + 3 ); // skip "FT_" + const char** functNames = getFunctNames(); + int ft = 0; + for ( ; ft < SMESH::FT_Undefined; ++ft ) + if ( name == ( functNames[ft] + 3 )) + break; + + //ASSERT( strcmp( str, FunctorTypeToString( SMESH::FunctorType( ft ))) == 0 ); + + return SMESH::FunctorType( ft ); + } + + //================================================================================ + /*! + * \brief calls OnBaseObjModified(), if who != this, and myWaiters[i]->Modified(who) + */ + //================================================================================ + + void NotifyerAndWaiter::Modified( bool removed, NotifyerAndWaiter* who ) + { + if ( who != 0 && who != this ) + OnBaseObjModified( who, removed ); + else + who = this; + + std::list waiters = myWaiters; // myWaiters can be changed by Modified() + std::list::iterator i = waiters.begin(); + for ( ; i != waiters.end(); ++i ) + (*i)->Modified( removed, who ); + } + + //================================================================================ + /*! + * \brief Stores an object to be notified on change of predicate + */ + //================================================================================ + + void NotifyerAndWaiter::AddModifWaiter( NotifyerAndWaiter* waiter ) + { + if ( waiter ) + myWaiters.push_back( waiter ); + } + + //================================================================================ + /*! + * \brief Removes an object to be notified on change of predicate + */ + //================================================================================ + + void NotifyerAndWaiter::RemoveModifWaiter( NotifyerAndWaiter* waiter ) + { + myWaiters.remove( waiter ); + } + + //================================================================================ + /*! + * \brief Checks if a waiter is among myWaiters, maybe nested + */ + //================================================================================ + + bool NotifyerAndWaiter::ContainModifWaiter( NotifyerAndWaiter* waiter ) + { + bool is = ( waiter == this ); + + std::list::iterator w = myWaiters.begin(); + for ( ; !is && w != myWaiters.end(); ++w ) + is = (*w)->ContainModifWaiter( waiter ); + + return is; + } } diff --git a/src/SMESH_I/SMESH_Gen_No_Session_i.cxx b/src/SMESH_I/SMESH_Gen_No_Session_i.cxx index db261e7d4..2b4e33cc2 100644 --- a/src/SMESH_I/SMESH_Gen_No_Session_i.cxx +++ b/src/SMESH_I/SMESH_Gen_No_Session_i.cxx @@ -29,12 +29,19 @@ SMESH_Gen_No_Session_i::SMESH_Gen_No_Session_i( CORBA::ORB_ptr orb, const char* instanceName, const char* interfaceName):SMESH_Gen_i(orb,poa,contId,instanceName,interfaceName,false) { - myNS = new SALOME_Fake_NamingService; } 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; } diff --git a/src/SMESH_I/SMESH_Gen_i.cxx b/src/SMESH_I/SMESH_Gen_i.cxx index 107a1ef4f..30d035262 100644 --- a/src/SMESH_I/SMESH_Gen_i.cxx +++ b/src/SMESH_I/SMESH_Gen_i.cxx @@ -102,6 +102,7 @@ #include "SMESH_PreMeshInfo.hxx" #include "SMESH_PythonDump.hxx" #include "SMESH_ControlsDef.hxx" +#include // to pass CORBA exception through SMESH_TRY #define SMY_OWN_CATCH catch( SALOME::SALOME_Exception& se ) { throw se; } @@ -237,6 +238,14 @@ CORBA::Object_var SMESH_Gen_i::SObjectToObject( SALOMEDS::SObject_ptr theSObject return anObj; } +// Set Naming Service object +void SMESH_Gen_i::SetNS(SALOME_NamingService_Abstract *ns) +{ + if(myNS) + delete myNS; + myNS = ns; +} + //============================================================================= /*! * GetNS [ static ] @@ -247,7 +256,7 @@ CORBA::Object_var SMESH_Gen_i::SObjectToObject( SALOMEDS::SObject_ptr theSObject SALOME_NamingService_Abstract* SMESH_Gen_i::GetNS() { - if ( myNS == NULL ) { + if ( !myNS ) { myNS = SINGLETON_::Instance(); ASSERT(SINGLETON_::IsAlreadyExisting()); myNS->init_orb( GetORB() ); @@ -452,18 +461,17 @@ GenericHypothesisCreator_i* SMESH_Gen_i::getHypothesisCreator(const char* theHyp // load plugin library if(MYDEBUG) MESSAGE("Loading server meshers plugin library ..."); #ifdef WIN32 -#ifdef UNICODE +# ifdef UNICODE const wchar_t* path = Kernel_Utils::decode_s(aPlatformLibName); -#else + SMESHUtils::ArrayDeleter deleter( path ); +# else const char* path = aPlatformLibName.c_str(); -#endif +# endif #else const char* path = aPlatformLibName.c_str(); #endif LibHandle libHandle = LoadLib( path ); -#if defined(WIN32) && defined(UNICODE) - delete path; -#endif + if (!libHandle) { // report any error, if occurred @@ -2699,10 +2707,10 @@ SMESH_Gen_i::ConcatenateCommon(const SMESH::ListOfIDSources& theMeshesArray, { // type names const char* typeNames[] = { "All","Nodes","Edges","Faces","Volumes","0DElems","Balls" }; - { // check of typeNames: compilation failure mains that NB_ELEMENT_TYPES changed: - const int nbNames = sizeof(typeNames) / sizeof(const char*); - int _assert[( nbNames == SMESH::NB_ELEMENT_TYPES ) ? 2 : -1 ]; _assert[0]=_assert[1]=0; - } + + // check of typeNames: compilation failure mains that NB_ELEMENT_TYPES changed: + static_assert( sizeof(typeNames) / sizeof(const char*) ==SMESH::NB_ELEMENT_TYPES, + "Update names of ElementType's!!!" ); SMESH::smIdType_array_var curState = newMesh->GetNbElementsByType(); @@ -4198,8 +4206,9 @@ SALOMEDS::TMPFile* SMESH_Gen_i::Save( SALOMEDS::SComponent_ptr theComponent, system(cmd.ToCString()); // MED writer to be used by storage process - DriverMED_W_SMESHDS_Mesh myWriter; - myWriter.SetFile( meshfile.ToCString() ); + DriverMED_W_SMESHDS_Mesh writer; + writer.SetFile( meshfile.ToCString() ); + //writer.SetSaveNumbers( false ); // bos #24400 -- it leads to change of element IDs // IMP issue 20918 // SetStoreName() to groups before storing hypotheses to let them refer to @@ -4406,8 +4415,8 @@ SALOMEDS::TMPFile* SMESH_Gen_i::Save( SALOMEDS::SComponent_ptr theComponent, // check if the mesh is not empty if ( mySMESHDSMesh->NbNodes() > 0 ) { // write mesh data to med file - myWriter.SetMesh( mySMESHDSMesh ); - myWriter.SetMeshId( id ); + writer.SetMesh( mySMESHDSMesh ); + writer.SetMeshId( id ); strHasData = "1"; } aSize[ 0 ] = strHasData.length() + 1; @@ -4881,7 +4890,7 @@ SALOMEDS::TMPFile* SMESH_Gen_i::Save( SALOMEDS::SComponent_ptr theComponent, // Pass SMESHDS_Group to MED writer SMESHDS_Group* aGrpDS = dynamic_cast( aGrpBaseDS ); if ( aGrpDS ) - myWriter.AddGroup( aGrpDS ); + writer.AddGroup( aGrpDS ); // write reference on a shape if exists SMESHDS_GroupOnGeom* aGeomGrp = @@ -4906,7 +4915,7 @@ SALOMEDS::TMPFile* SMESH_Gen_i::Save( SALOMEDS::SComponent_ptr theComponent, else // shape ref is invalid: { // save a group on geometry as ordinary group - myWriter.AddGroup( aGeomGrp ); + writer.AddGroup( aGeomGrp ); } } else if ( SMESH_GroupOnFilter_i* aFilterGrp_i = @@ -4929,7 +4938,7 @@ SALOMEDS::TMPFile* SMESH_Gen_i::Save( SALOMEDS::SComponent_ptr theComponent, if ( strcmp( strHasData.c_str(), "1" ) == 0 ) { // Flush current mesh information into MED file - myWriter.Perform(); + writer.Perform(); // save info on nb of elements SMESH_PreMeshInfo::SaveToFile( myImpl, id, aFile ); @@ -5185,7 +5194,8 @@ bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent, TCollection_AsciiString aStudyName( "" ); if ( isMultiFile ) { CORBA::WString_var url = aStudy->URL(); - aStudyName = (char*)SALOMEDS_Tool::GetNameFromPath( Kernel_Utils::encode(url.in()) ).c_str(); + SMESHUtils::ArrayDeleter urlMulibyte( Kernel_Utils::encode( url.in()) ); + aStudyName = (char*)SALOMEDS_Tool::GetNameFromPath( urlMulibyte.get() ).c_str(); } // Set names of temporary files TCollection_AsciiString filename = tmpDir + aStudyName + "_SMESH.hdf"; @@ -5539,7 +5549,7 @@ bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent, } } // reading MESHes - // As all object that can be referred by hypothesis are created, + // As all objects that can be referred by hypothesis are created, // we can restore hypothesis data list< pair< SMESH_Hypothesis_i*, string > >::iterator hyp_data; @@ -5907,7 +5917,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 ); @@ -5986,13 +5997,8 @@ bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent, aDataset->ReadFromDisk((char*) dataString.data() ); aDataset->CloseOnDisk(); - std::istringstream istream( dataString.data() ); - boost::archive::text_iarchive archive( istream ); std::list< std::list< std::string > > orderEntryLists; - try { - archive >> orderEntryLists; - } - catch (...) {} + SMESHUtils::BoostTxtArchive( dataString ) >> orderEntryLists; TListOfListOfInt anOrderIds; for ( const std::list< std::string >& entryList : orderEntryLists ) @@ -6235,8 +6241,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; } diff --git a/src/SMESH_I/SMESH_Gen_i.hxx b/src/SMESH_I/SMESH_Gen_i.hxx index 1d1ed678b..648b1d2f5 100644 --- a/src/SMESH_I/SMESH_Gen_i.hxx +++ b/src/SMESH_I/SMESH_Gen_i.hxx @@ -104,6 +104,8 @@ public: static CORBA::ORB_var GetORB() { return myOrb;} // Get SMESH module's POA object static PortableServer::POA_var GetPOA() { return myPoa;} + // Set Naming Service object + static void SetNS(SALOME_NamingService_Abstract *ns); // Get Naming Service object static SALOME_NamingService_Abstract* GetNS(); // Get SALOME_LifeCycleCORBA object diff --git a/src/SMESH_I/SMESH_Gen_i_1.cxx b/src/SMESH_I/SMESH_Gen_i_1.cxx index d31ccf2d8..565fa023b 100644 --- a/src/SMESH_I/SMESH_Gen_i_1.cxx +++ b/src/SMESH_I/SMESH_Gen_i_1.cxx @@ -548,8 +548,11 @@ SALOMEDS::SComponent_ptr SMESH_Gen_i::PublishComponent() 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 - + 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,7 +561,8 @@ 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 && compDataType == cdt.in() && ior == ior_i.in()) { father = f_i; break; } diff --git a/src/SMESH_I/SMESH_Group_i.cxx b/src/SMESH_I/SMESH_Group_i.cxx index 9828ac984..1ee929550 100644 --- a/src/SMESH_I/SMESH_Group_i.cxx +++ b/src/SMESH_I/SMESH_Group_i.cxx @@ -43,8 +43,6 @@ #include "utilities.h" -using namespace SMESH; - //============================================================================= /*! * @@ -158,7 +156,7 @@ void SMESH_GroupBase_i::SetName( const char* theName ) aGen->SetName( anSO, theName ); // Update Python script - TPythonDump() << anSO << ".SetName( '" << theName << "' )"; + SMESH::TPythonDump() << anSO << ".SetName( '" << theName << "' )"; } } @@ -264,7 +262,7 @@ void SMESH_Group_i::Clear() myPreMeshInfo->FullLoadFromFile(); // Update Python script - TPythonDump() << SMESH::SMESH_Group_var(_this()) << ".Clear()"; + SMESH::TPythonDump() << SMESH::SMESH_Group_var(_this()) << ".Clear()"; // Clear the group SMESHDS_Group* aGroupDS = dynamic_cast( GetGroupDS() ); @@ -304,7 +302,7 @@ SMESH::smIdType SMESH_Group_i::Add( const SMESH::smIdType_array& theIDs ) myPreMeshInfo->FullLoadFromFile(); // Update Python script - TPythonDump() << "nbAdd = " << SMESH::SMESH_Group_var(_this()) << ".Add( " << theIDs << " )"; + SMESH::TPythonDump() << "nbAdd = " << SMESH::SMESH_Group_var(_this()) << ".Add( " << theIDs << " )"; // Add elements to the group SMESHDS_Group* aGroupDS = dynamic_cast( GetGroupDS() ); @@ -335,7 +333,7 @@ SMESH::smIdType SMESH_Group_i::Remove( const SMESH::smIdType_array& theIDs ) myPreMeshInfo->FullLoadFromFile(); // Update Python script - TPythonDump() << "nbDel = " << SMESH::SMESH_Group_var(_this()) + SMESH::TPythonDump() << "nbDel = " << SMESH::SMESH_Group_var(_this()) << ".Remove( " << theIDs << " )"; // Remove elements from the group @@ -364,10 +362,10 @@ SMESH::smIdType SMESH_Group_i::Remove( const SMESH::smIdType_array& theIDs ) typedef bool (SMESHDS_Group::*TFunChangeGroup)(const smIdType); CORBA::Long -ChangeByPredicate( SMESH::Predicate_i* thePredicate, - SMESHDS_GroupBase* theGroupBase, - NotifyerAndWaiter* theGroupImpl, - TFunChangeGroup theFun) +ChangeByPredicate( SMESH::Predicate_i* thePredicate, + SMESHDS_GroupBase* theGroupBase, + SMESH::NotifyerAndWaiter* theGroupImpl, + TFunChangeGroup theFun) { CORBA::Long aNb = 0; if(SMESHDS_Group* aGroupDS = dynamic_cast(theGroupBase)){ @@ -394,8 +392,8 @@ AddByPredicate( SMESH::Predicate_ptr thePredicate ) myPreMeshInfo->FullLoadFromFile(); if(SMESH::Predicate_i* aPredicate = SMESH::GetPredicate(thePredicate)){ - TPythonDump() << SMESH::SMESH_Group_var(_this()) - << ".AddByPredicate( " << aPredicate << " )"; + SMESH::TPythonDump() << SMESH::SMESH_Group_var(_this()) + << ".AddByPredicate( " << aPredicate << " )"; return ChangeByPredicate( aPredicate, GetGroupDS(), this, &SMESHDS_Group::Add ); } return 0; @@ -409,8 +407,8 @@ RemoveByPredicate( SMESH::Predicate_ptr thePredicate ) myPreMeshInfo->FullLoadFromFile(); if(SMESH::Predicate_i* aPredicate = SMESH::GetPredicate(thePredicate)){ - TPythonDump() << SMESH::SMESH_Group_var(_this()) - << ".RemoveByPredicate( " << aPredicate << " )"; + SMESH::TPythonDump() << SMESH::SMESH_Group_var(_this()) + << ".RemoveByPredicate( " << aPredicate << " )"; return ChangeByPredicate(aPredicate,GetGroupDS(),this, &SMESHDS_Group::Remove); } return 0; @@ -421,7 +419,7 @@ SMESH::smIdType SMESH_Group_i::AddFrom( SMESH::SMESH_IDSource_ptr theSource ) if ( myPreMeshInfo ) myPreMeshInfo->FullLoadFromFile(); - TPythonDump pd; + SMESH::TPythonDump pd; long prevNb = Size(); SMESHDS_Group* aGroupDS = dynamic_cast( GetGroupDS() ); if (aGroupDS) { @@ -441,7 +439,7 @@ SMESH::smIdType SMESH_Group_i::AddFrom( SMESH::SMESH_IDSource_ptr theSource ) //============================================================================= /*! - * + * Return ID of theIndex-th group item */ //============================================================================= @@ -475,7 +473,7 @@ SMESH::smIdType_array* SMESH_GroupBase_i::GetListOfID() smIdType aSize = aGroupDS->Extent(); aRes->length(aSize); SMDS_ElemIteratorPtr it = aGroupDS->GetElements(); - for (smIdType i = 0; it->more(); i++) + for (::smIdType i = 0; it->more(); i++) aRes[i] = it->next()->GetID(); if ( 0 < aSize && aSize < 100 ) // for comfortable testing ;) @@ -639,9 +637,9 @@ void SMESH_GroupBase_i::SetColor(const SALOMEDS::Color& color) if ( oldColor != aQColor ) { aGroupDS->SetColor(aQColor); - TPythonDump()<< SMESH::SMESH_GroupBase_var(_this()) - << ".SetColor( SALOMEDS.Color( " - <SetColorGroup(color); - TPythonDump()<GetGen()->HighLightInvalid( me, false ); - TPythonDump()<< me <<".SetFilter( "<< theFilter <<" )"; + SMESH::TPythonDump()<< me <<".SetFilter( "<< theFilter <<" )"; } //================================================================================ @@ -856,7 +854,7 @@ void SMESH_GroupOnFilter_i::SetFilter(SMESH::Filter_ptr theFilter) SMESH::Filter_ptr SMESH_GroupOnFilter_i::GetFilter() { SMESH::Filter_var f = myFilter; - TPythonDump() << f << " = " << SMESH::SMESH_GroupOnFilter_var(_this()) << ".GetFilter()"; + SMESH::TPythonDump() << f << " = " << SMESH::SMESH_GroupOnFilter_var(_this()) << ".GetFilter()"; return f._retn(); } @@ -938,7 +936,7 @@ SMESH::smIdType_array* SMESH_GroupOnFilter_i::GetMeshInfo() if ( g->GetType() != SMDSAbs_Node ) { - std::vector< SMESH::smIdType > nbElems = static_cast< SMESHDS_GroupOnFilter* >( g )->GetMeshInfo(); + std::vector< smIdType > nbElems = static_cast< SMESHDS_GroupOnFilter* >( g )->GetMeshInfo(); for ( size_t i = SMESH::Entity_Node; i < SMESH::Entity_Last; i++) if ( i < nbElems.size() ) aRes[i] = nbElems[ i ]; @@ -1039,7 +1037,7 @@ SMESH::Filter_ptr SMESH_GroupOnFilter_i::StringToFilter(const std::string& thePe } // create a filter - TPythonDump pd; + SMESH::TPythonDump pd; SMESH::FilterManager_i* aFilterMgr = new SMESH::FilterManager_i(); filter = aFilterMgr->CreateFilter(); filter->SetCriteria( criteria.inout() ); diff --git a/src/SMESH_I/SMESH_Group_i.hxx b/src/SMESH_I/SMESH_Group_i.hxx index 676a27ed6..a0f54c3b5 100644 --- a/src/SMESH_I/SMESH_Group_i.hxx +++ b/src/SMESH_I/SMESH_Group_i.hxx @@ -109,7 +109,7 @@ class SMESH_I_EXPORT SMESH_GroupBase_i: // Internal C++ interface - int GetLocalID() const { return myLocalID; } + int GetLocalID() const { return myLocalID; } // return group persistent ID SMESH_Mesh_i* GetMeshServant() const { return myMeshServant; } SMESH_Group* GetSmeshGroup() const; SMESHDS_GroupBase* GetGroupDS() const; diff --git a/src/SMESH_I/SMESH_Measurements_i.cxx b/src/SMESH_I/SMESH_Measurements_i.cxx index f81c0573b..ce71af650 100644 --- a/src/SMESH_I/SMESH_Measurements_i.cxx +++ b/src/SMESH_I/SMESH_Measurements_i.cxx @@ -22,10 +22,6 @@ // File : SMESH_Measurements_i.cxx // Author : Pavel TELKOV, Open CASCADE S.A.S. (pavel.telkov@opencascade.com) -#ifdef WIN32 -#define NOMINMAX -#endif - #include "SMESH_Measurements_i.hxx" #include "SMDS_ElemIterator.hxx" @@ -40,7 +36,7 @@ #include -using namespace SMESH; +//using namespace SMESH; /** * this local function to avoid uninitialized fields @@ -80,7 +76,7 @@ SMESH::Measurements_ptr SMESH_Gen_i::CreateMeasurements() // name : Measurements_i // Purpose : Constructor //======================================================================= -Measurements_i::Measurements_i() +SMESH::Measurements_i::Measurements_i() : SALOME::GenericObj_i( SMESH_Gen_i::GetPOA() ) { //Base class Salome_GenericObject do it inmplicitly by overriding PortableServer::POA_ptr _default_POA() method @@ -92,7 +88,7 @@ Measurements_i::Measurements_i() // name : ~Measurements_i // Purpose : Destructor //======================================================================= -Measurements_i::~Measurements_i() +SMESH::Measurements_i::~Measurements_i() { //TPythonDump()<GetMesh(); - SMESH_Mesh_i* anImplPtr = DownCast( mesh ); + SMESH_Mesh_i* anImplPtr = SMESH::DownCast( mesh ); if (anImplPtr) return anImplPtr->GetImpl().GetMeshDS(); } @@ -187,7 +183,7 @@ static double getNumericalValue(SMESH::SMESH_IDSource_ptr theSource, // name : MinDistance // Purpose : minimal distance between two given entities //======================================================================= -SMESH::Measure Measurements_i::MinDistance +SMESH::Measure SMESH::Measurements_i::MinDistance (SMESH::SMESH_IDSource_ptr theSource1, SMESH::SMESH_IDSource_ptr theSource2) { @@ -289,7 +285,7 @@ static void enlargeBoundingBox(const SMESH::SMESH_IDSource_ptr theObject, if ( !aMesh ) return; - if ( DownCast( theObject )) // theObject is mesh + if (SMESH::DownCast( theObject )) // theObject is mesh { for (SMDS_NodeIteratorPtr aNodeIter = aMesh->nodesIterator(); aNodeIter->more(); ) enlargeBoundingBox( aNodeIter->next(), theMeasure); @@ -318,7 +314,7 @@ static void enlargeBoundingBox(const SMESH::SMESH_IDSource_ptr theObject, // name : BoundingBox // Purpose : compute common bounding box of entities //======================================================================= -SMESH::Measure Measurements_i::BoundingBox (const SMESH::ListOfIDSources& theSources) +SMESH::Measure SMESH::Measurements_i::BoundingBox (const SMESH::ListOfIDSources& theSources) { SMESH::Measure aMeasure; initMeasure(aMeasure); @@ -334,7 +330,7 @@ SMESH::Measure Measurements_i::BoundingBox (const SMESH::ListOfIDSources& theSou // name : Length // Purpose : sum of length of 1D elements of the source //======================================================================= -double Measurements_i::Length(SMESH::SMESH_IDSource_ptr theSource) +double SMESH::Measurements_i::Length(SMESH::SMESH_IDSource_ptr theSource) { return getNumericalValue( theSource, SMESH::Controls::NumericalFunctorPtr(new SMESH::Controls::Length()) ); } @@ -343,7 +339,7 @@ double Measurements_i::Length(SMESH::SMESH_IDSource_ptr theSource) // name : Area // Purpose : sum of area of 2D elements of the source //======================================================================= -double Measurements_i::Area(SMESH::SMESH_IDSource_ptr theSource) +double SMESH::Measurements_i::Area(SMESH::SMESH_IDSource_ptr theSource) { return getNumericalValue( theSource, SMESH::Controls::NumericalFunctorPtr(new SMESH::Controls::Area()) ); } @@ -352,7 +348,7 @@ double Measurements_i::Area(SMESH::SMESH_IDSource_ptr theSource) // name : Volume // Purpose : sum of volume of 3D elements of the source //======================================================================= -double Measurements_i::Volume(SMESH::SMESH_IDSource_ptr theSource) +double SMESH::Measurements_i::Volume(SMESH::SMESH_IDSource_ptr theSource) { return getNumericalValue( theSource, SMESH::Controls::NumericalFunctorPtr(new SMESH::Controls::Volume()) ); } @@ -362,7 +358,7 @@ double Measurements_i::Volume(SMESH::SMESH_IDSource_ptr theSource) //purpose : return gravity center of the source: average coordinates of all nodes //======================================================================= -SMESH::PointStruct Measurements_i::GravityCenter(SMESH::SMESH_IDSource_ptr theSource) +SMESH::PointStruct SMESH::Measurements_i::GravityCenter(SMESH::SMESH_IDSource_ptr theSource) { SMESH::PointStruct grCenter = { 0.,0.,0. }; const SMESHDS_Mesh* mesh = getMesh( theSource ); @@ -404,9 +400,9 @@ SMESH::PointStruct Measurements_i::GravityCenter(SMESH::SMESH_IDSource_ptr theSo //purpose : Return angle in radians defined by 3 points <(p1,p2,p3) //======================================================================= -CORBA::Double Measurements_i::Angle(const SMESH::PointStruct& p1, - const SMESH::PointStruct& p2, - const SMESH::PointStruct& p3 ) +CORBA::Double SMESH::Measurements_i::Angle(const SMESH::PointStruct& p1, + const SMESH::PointStruct& p2, + const SMESH::PointStruct& p3 ) { gp_Vec v1( p1.x - p2.x, p1.y - p2.y, p1.z - p2.z ); gp_Vec v2( p3.x - p2.x, p3.y - p2.y, p3.z - p2.z ); diff --git a/src/SMESH_I/SMESH_MeshEditor_i.cxx b/src/SMESH_I/SMESH_MeshEditor_i.cxx index d96c5c99e..f11615845 100644 --- a/src/SMESH_I/SMESH_MeshEditor_i.cxx +++ b/src/SMESH_I/SMESH_MeshEditor_i.cxx @@ -102,7 +102,7 @@ namespace MeshEditor_I { //!< Constructor TPreviewMesh(SMDSAbs_ElementType previewElements = SMDSAbs_All) { _isShapeToMesh = (_id = 0); - _myMeshDS = new SMESHDS_Mesh( _id, true ); + _meshDS = new SMESHDS_Mesh( _id, true ); myPreviewType = previewElements; } //!< Copy a set of elements @@ -155,8 +155,8 @@ namespace MeshEditor_I { //!< Copy a node SMDS_MeshNode* Copy( const SMDS_MeshNode* anElemNode ) { - return _myMeshDS->AddNodeWithID(anElemNode->X(), anElemNode->Y(), anElemNode->Z(), - anElemNode->GetID()); + return _meshDS->AddNodeWithID(anElemNode->X(), anElemNode->Y(), anElemNode->Z(), + anElemNode->GetID()); } void RemoveAll() { @@ -279,13 +279,13 @@ namespace MeshEditor_I { SMDS_MeshElement::Filter & filter = *aFilter; if ( aType == SMDSAbs_Node ) - for ( SMESH::smIdType i = 0; i < IDs.length(); i++ ) { + for ( CORBA::ULong i = 0; i < IDs.length(); i++ ) { const SMDS_MeshElement * elem = aMesh->FindNode( IDs[i] ); if ( filter( elem )) aMap.insert( aMap.end(), elem ); } else - for ( SMESH::smIdType i = 0; iFindElement( IDs[i] ); if ( filter( elem )) aMap.insert( aMap.end(), elem ); @@ -789,7 +789,7 @@ SMESH_MeshEditor_i::RemoveElements(const SMESH::smIdType_array & IDsOfElements) list< smIdType > IdList; - for ( SMESH::smIdType i = 0; i < IDsOfElements.length(); i++ ) + for ( CORBA::ULong i = 0; i < IDsOfElements.length(); i++ ) IdList.push_back( IDsOfElements[i] ); // Update Python script @@ -817,7 +817,7 @@ CORBA::Boolean SMESH_MeshEditor_i::RemoveNodes(const SMESH::smIdType_array & IDs initData(); list< smIdType > IdList; - for ( SMESH::smIdType i = 0; i < IDsOfNodes.length(); i++) + for ( CORBA::ULong i = 0; i < IDsOfNodes.length(); i++) IdList.push_back( IDsOfNodes[i] ); // Update Python script @@ -1578,7 +1578,7 @@ CORBA::Boolean SMESH_MeshEditor_i::Reorient(const SMESH::smIdType_array & IDsOfE SMESH_TRY; initData(); - for ( SMESH::smIdType i = 0; i < IDsOfElements.length(); i++ ) + for ( CORBA::ULong i = 0; i < IDsOfElements.length(); i++ ) { SMESH::smIdType index = IDsOfElements[i]; const SMDS_MeshElement * elem = getMeshDS()->FindElement(index); @@ -2252,7 +2252,7 @@ SMESH_MeshEditor_i::smooth(const SMESH::smIdType_array & IDsOfElements, arrayToSet(IDsOfElements, aMesh, elements, SMDSAbs_Face); set fixedNodes; - for ( SMESH::smIdType i = 0; i < IDsOfFixedNodes.length(); i++) { + for ( CORBA::ULong i = 0; i < IDsOfFixedNodes.length(); i++) { SMESH::smIdType index = IDsOfFixedNodes[i]; const SMDS_MeshNode * node = aMesh->FindNode(index); if ( node ) @@ -4342,7 +4342,7 @@ void SMESH_MeshEditor_i::MergeElements(const SMESH::array_of_long_array& theGrou if ( elemTypes->length() == 1 && elemTypes[0] == SMESH::NODE ) continue; SMESH::smIdType_array_var elementsId = theElementsToKeep[i]->GetIDs(); - for ( SMESH::smIdType j = 0; j < elementsId->length(); ++j ) + for ( CORBA::ULong j = 0; j < elementsId->length(); ++j ) idsToKeep.Add( elementsId[ j ]); } @@ -4353,7 +4353,7 @@ void SMESH_MeshEditor_i::MergeElements(const SMESH::array_of_long_array& theGrou const SMESH::long_array& anElemsIDGroup = theGroupsOfElementsID[ i ]; aListOfListOfElementsID.push_back( list< smIdType >() ); list< smIdType >& aListOfElemsID = aListOfListOfElementsID.back(); - for ( SMESH::smIdType j = 0; j < anElemsIDGroup.length(); j++ ) + for ( CORBA::ULong j = 0; j < anElemsIDGroup.length(); j++ ) { SMESH::smIdType id = anElemsIDGroup[ j ]; if ( idsToKeep.Contains( id )) aListOfElemsID.push_front( id ); diff --git a/src/SMESH_I/SMESH_MeshEditor_i.hxx b/src/SMESH_I/SMESH_MeshEditor_i.hxx index 2f152c334..69f62d539 100644 --- a/src/SMESH_I/SMESH_MeshEditor_i.hxx +++ b/src/SMESH_I/SMESH_MeshEditor_i.hxx @@ -93,7 +93,7 @@ public: SMESH::SMESH_IDSource_ptr MakeIDSource(const SMESH::smIdType_array& IDsOfElements, SMESH::ElementType type); static bool IsTemporaryIDSource( SMESH::SMESH_IDSource_ptr& idSource ); - static SMESH::smIdType* GetTemporaryIDs( SMESH::SMESH_IDSource_ptr& idSource, smIdType& nbIds ); + static SMESH::smIdType* GetTemporaryIDs( SMESH::SMESH_IDSource_ptr& idSource, SMESH::smIdType& nbIds ); /*! * \brief Generates the unique group name diff --git a/src/SMESH_I/SMESH_Mesh_i.cxx b/src/SMESH_I/SMESH_Mesh_i.cxx index b2551f739..c63eccd3b 100644 --- a/src/SMESH_I/SMESH_Mesh_i.cxx +++ b/src/SMESH_I/SMESH_Mesh_i.cxx @@ -3684,6 +3684,25 @@ void SMESH_Mesh_i::PrepareForWriting (const char* file, bool overwrite) } } +/*! + Return a MeshName + */ +std::string SMESH_Mesh_i::generateMeshName() +{ + string aMeshName = "Mesh"; + SALOMEDS::Study_var aStudy = SMESH_Gen_i::GetSMESHGen()->getStudyServant(); + if ( !aStudy->_is_nil() ) + { + SALOMEDS::SObject_wrap aMeshSO = _gen_i->ObjectToSObject( _this() ); + if ( !aMeshSO->_is_nil() ) + { + CORBA::String_var name = aMeshSO->GetName(); + aMeshName = name; + } + } + return aMeshName; +} + //================================================================================ /*! * \brief Prepare a file for export and pass names of mesh groups from study to mesh DS @@ -3698,13 +3717,11 @@ string SMESH_Mesh_i::prepareMeshNameAndGroups(const char* file, { // Perform Export PrepareForWriting(file, overwrite); - string aMeshName = "Mesh"; + string aMeshName(this->generateMeshName()); SALOMEDS::Study_var aStudy = SMESH_Gen_i::GetSMESHGen()->getStudyServant(); if ( !aStudy->_is_nil() ) { SALOMEDS::SObject_wrap aMeshSO = _gen_i->ObjectToSObject( _this() ); if ( !aMeshSO->_is_nil() ) { - CORBA::String_var name = aMeshSO->GetName(); - aMeshName = name; // asv : 27.10.04 : fix of 6903: check for StudyLocked before adding attributes if ( !aStudy->GetProperties()->IsLocked() ) { @@ -3763,6 +3780,23 @@ void SMESH_Mesh_i::ExportMED(const char* file, SMESH_CATCH( SMESH::throwCorbaException ); } +CORBA::LongLong SMESH_Mesh_i::ExportMEDCoupling(CORBA::Boolean auto_groups, CORBA::Boolean autoDimension) +{ + MEDCoupling::MCAuto data; + SMESH_TRY; + // TODO : Fix me ! 2 next lines are required + if( !this->_gen_i->isSSLMode() ) + SMESH::throwCorbaException("SMESH_Mesh_i::ExportMEDCoupling : only for embedded mode !"); + if ( _preMeshInfo ) + _preMeshInfo->FullLoadFromFile(); + + string aMeshName = this->generateMeshName(); + data = _impl->ExportMEDCoupling( aMeshName.c_str(), auto_groups, 0, autoDimension ); + SMESH_CATCH( SMESH::throwCorbaException ); + MEDCoupling::DataArrayByte *ret(data.retn()); + return reinterpret_cast(ret); +} + //================================================================================ /*! * \brief Export a mesh to a SAUV file @@ -3790,7 +3824,7 @@ void SMESH_Mesh_i::ExportSAUV( const char* file, CORBA::Boolean auto_groups ) */ //================================================================================ -void SMESH_Mesh_i::ExportDAT (const char *file) +void SMESH_Mesh_i::ExportDAT (const char *file, CORBA::Boolean renumber ) { SMESH_TRY; if ( _preMeshInfo ) @@ -3799,11 +3833,12 @@ void SMESH_Mesh_i::ExportDAT (const char *file) // check names of groups checkGroupNames(); // Update Python script - TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportDAT( r'" << file << "' )"; + TPythonDump() << SMESH::SMESH_Mesh_var(_this()) + << ".ExportDAT( r'" << file<< ", " << renumber << "' )"; // Perform Export - PrepareForWriting(file); - _impl->ExportDAT(file); + PrepareForWriting( file ); + _impl->ExportDAT( file, /*part=*/nullptr, renumber ); SMESH_CATCH( SMESH::throwCorbaException ); } @@ -3814,7 +3849,7 @@ void SMESH_Mesh_i::ExportDAT (const char *file) */ //================================================================================ -void SMESH_Mesh_i::ExportUNV (const char *file) +void SMESH_Mesh_i::ExportUNV (const char *file, CORBA::Boolean renumber) { SMESH_TRY; if ( _preMeshInfo ) @@ -3823,11 +3858,12 @@ void SMESH_Mesh_i::ExportUNV (const char *file) // check names of groups checkGroupNames(); // Update Python script - TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportUNV( r'" << file << "' )"; + TPythonDump() << SMESH::SMESH_Mesh_var(_this()) + << ".ExportUNV( r'" << file << "' " << renumber << "' )"; // Perform Export - PrepareForWriting(file); - _impl->ExportUNV(file); + PrepareForWriting( file ); + _impl->ExportUNV( file, /*part=*/nullptr, renumber ); SMESH_CATCH( SMESH::throwCorbaException ); } @@ -3862,23 +3898,64 @@ void SMESH_Mesh_i::ExportSTL (const char *file, const bool isascii) SMESH_CATCH( SMESH::throwCorbaException ); } +//================================================================================ + +class MEDFileSpeCls +{ +public: + MEDFileSpeCls(const char * file, + CORBA::Boolean overwrite, + CORBA::Long version) + :_file(file), _overwrite(overwrite), _version(version) + {} + std::string prepareMeshNameAndGroups(SMESH_Mesh_i& self) + { + return self.prepareMeshNameAndGroups(_file.c_str(),_overwrite); + } + + void exportTo(SMESH_Mesh *mesh, const std::string& aMeshName, CORBA::Boolean auto_groups, + SMESH_MeshPartDS* partDS, CORBA::Boolean autoDimension, bool have0dField, + CORBA::Double ZTolerance, CORBA::Boolean saveNumbers ) + { + mesh->ExportMED( _file.c_str(), aMeshName.c_str(), auto_groups, _version, + partDS, autoDimension, have0dField, ZTolerance, saveNumbers ); + } + + void exportField(SMESH_Mesh_i& self, const std::string& aMeshName, bool have0dField, + SMESHDS_Mesh *meshDS, const GEOM::ListOfFields& fields, + const char*geomAssocFields) + { + DriverMED_W_Field fieldWriter; + fieldWriter.SetFile( _file.c_str() ); + fieldWriter.SetMeshName( aMeshName ); + fieldWriter.AddODOnVertices( have0dField ); + self.exportMEDFields( fieldWriter, meshDS, fields, geomAssocFields ); + } + + void prepareForWriting(SMESH_Mesh_i& self) { self.PrepareForWriting(_file.c_str(), _overwrite); } + +private: + std::string _file; + CORBA::Boolean _overwrite; + CORBA::Long _version; +}; + //================================================================================ /*! * \brief Export a part of mesh to a med file */ //================================================================================ -void SMESH_Mesh_i::ExportPartToMED(SMESH::SMESH_IDSource_ptr meshPart, - const char* file, - CORBA::Boolean auto_groups, - CORBA::Long version, - CORBA::Boolean overwrite, - CORBA::Boolean autoDimension, - const GEOM::ListOfFields& fields, - const char* geomAssocFields, - CORBA::Double ZTolerance) +template +void SMESH_Mesh_i::ExportPartToMEDCommon(SPECLS& speCls, + SMESH::SMESH_IDSource_ptr meshPart, + CORBA::Boolean auto_groups, + CORBA::Boolean autoDimension, + const GEOM::ListOfFields& fields, + const char* geomAssocFields, + CORBA::Double ZTolerance, + CORBA::Boolean saveNumbers) { - MESSAGE("MED version: "<< version); SMESH_TRY; if ( _preMeshInfo ) _preMeshInfo->FullLoadFromFile(); @@ -3900,8 +3977,7 @@ void SMESH_Mesh_i::ExportPartToMED(SMESH::SMESH_IDSource_ptr meshPart, if ( fieldShape->_is_nil() ) THROW_SALOME_CORBA_EXCEPTION( "Null shape under a field", SALOME::INTERNAL_ERROR ); if ( !fieldShape->IsSame( shapeToMesh ) ) - THROW_SALOME_CORBA_EXCEPTION - ( "Field defined not on shape", SALOME::BAD_PARAM); + THROW_SALOME_CORBA_EXCEPTION( "Field defined not on shape", SALOME::BAD_PARAM); if ( fields[i]->GetDimension() == 0 ) have0dField = true; } @@ -3924,10 +4000,9 @@ void SMESH_Mesh_i::ExportPartToMED(SMESH::SMESH_IDSource_ptr meshPart, if ( CORBA::is_nil( meshPart ) || SMESH::DownCast< SMESH_Mesh_i* >( meshPart )) { - aMeshName = prepareMeshNameAndGroups(file, overwrite); - _impl->ExportMED( file, aMeshName.c_str(), auto_groups, version, - 0, autoDimension, /*addODOnVertices=*/have0dField, - ZTolerance); + aMeshName = speCls.prepareMeshNameAndGroups(*this); + speCls.exportTo(_impl, aMeshName, auto_groups, nullptr, autoDimension, + have0dField, ZTolerance, saveNumbers ); meshDS = _impl->GetMeshDS(); } else @@ -3935,7 +4010,7 @@ void SMESH_Mesh_i::ExportPartToMED(SMESH::SMESH_IDSource_ptr meshPart, if ( _preMeshInfo ) _preMeshInfo->FullLoadFromFile(); - PrepareForWriting(file, overwrite); + speCls.prepareForWriting(*this); SALOMEDS::SObject_wrap SO = _gen_i->ObjectToSObject( meshPart ); if ( !SO->_is_nil() ) { @@ -3944,8 +4019,8 @@ void SMESH_Mesh_i::ExportPartToMED(SMESH::SMESH_IDSource_ptr meshPart, } SMESH_MeshPartDS* partDS = new SMESH_MeshPartDS( meshPart ); - _impl->ExportMED( file, aMeshName.c_str(), auto_groups, version, - partDS, autoDimension, /*addODOnVertices=*/have0dField, ZTolerance); + speCls.exportTo(_impl, aMeshName, auto_groups, partDS, autoDimension, + have0dField, ZTolerance, saveNumbers); meshDS = tmpDSDeleter._obj = partDS; } @@ -3953,15 +4028,35 @@ void SMESH_Mesh_i::ExportPartToMED(SMESH::SMESH_IDSource_ptr meshPart, if ( _impl->HasShapeToMesh() ) { - DriverMED_W_Field fieldWriter; - fieldWriter.SetFile( file ); - fieldWriter.SetMeshName( aMeshName ); - fieldWriter.AddODOnVertices( have0dField ); - - exportMEDFields( fieldWriter, meshDS, fields, geomAssocFields ); + speCls.exportField( *this, aMeshName, have0dField, meshDS, fields, geomAssocFields); } + SMESH_CATCH( SMESH::throwCorbaException ); +} +//================================================================================ +/*! + * \brief Export a part of mesh to a med file + */ +//================================================================================ + +void SMESH_Mesh_i::ExportPartToMED(SMESH::SMESH_IDSource_ptr meshPart, + const char* file, + CORBA::Boolean auto_groups, + CORBA::Long version, + CORBA::Boolean overwrite, + CORBA::Boolean autoDimension, + const GEOM::ListOfFields& fields, + const char* geomAssocFields, + CORBA::Double ZTolerance, + CORBA::Boolean saveNumbers) +{ + MESSAGE("MED version: "<< version); + + MEDFileSpeCls spe( file, overwrite, version ); + this->ExportPartToMEDCommon( spe, meshPart, auto_groups, autoDimension, fields, + geomAssocFields, ZTolerance, saveNumbers ); // dump + SMESH_TRY; GEOM::ListOfGBO_var goList = new GEOM::ListOfGBO; goList->length( fields.length() ); for ( size_t i = 0; i < fields.length(); ++i ) @@ -3978,10 +4073,74 @@ void SMESH_Mesh_i::ExportPartToMED(SMESH::SMESH_IDSource_ptr meshPart, << autoDimension << ", " << goList << ", '" << ( geomAssocFields ? geomAssocFields : "" ) << "'," - << TVar( ZTolerance ) + << TVar( ZTolerance ) << ", " + << saveNumbers << " )"; + SMESH_CATCH( SMESH::throwCorbaException ); +} + +//================================================================================ + +class MEDFileMemSpeCls +{ +public: + std::string prepareMeshNameAndGroups(SMESH_Mesh_i& self) { return self.generateMeshName(); } + + void exportTo(SMESH_Mesh *mesh, const std::string& aMeshName, CORBA::Boolean auto_groups, + SMESH_MeshPartDS* partDS, CORBA::Boolean autoDimension, bool have0dField, + CORBA::Double ZTolerance, CORBA::Boolean saveNumbers ) + { + _res = mesh->ExportMEDCoupling(aMeshName.c_str(), auto_groups, partDS, + autoDimension, have0dField, ZTolerance, saveNumbers ); + } + void prepareForWriting(SMESH_Mesh_i& /*self*/) { /* nothing here */ } + + void exportField(SMESH_Mesh_i& self, const std::string& aMeshName, bool have0dField, + SMESHDS_Mesh *meshDS, const GEOM::ListOfFields& fields, + const char*geomAssocFields) + { + DriverMED_W_Field_Mem fieldWriter(_res); + fieldWriter.SetMeshName( aMeshName ); + fieldWriter.AddODOnVertices( have0dField ); + self.exportMEDFields( fieldWriter, meshDS, fields, geomAssocFields ); + _res = fieldWriter.getData(); + } +public: + MEDCoupling::MCAuto getData() { return _res; } + +private: + MEDCoupling::MCAuto _res; +}; + +//================================================================================ +/*! + * \brief Export a part of mesh to a MEDCoupling DS + */ +//================================================================================ + +CORBA::LongLong SMESH_Mesh_i::ExportPartToMEDCoupling(SMESH::SMESH_IDSource_ptr meshPart, + CORBA::Boolean auto_groups, + CORBA::Boolean autoDimension, + const GEOM::ListOfFields& fields, + const char* geomAssocFields, + CORBA::Double ZTolerance, + CORBA::Boolean saveNumbers) +{ + MEDCoupling::MCAuto data; + + SMESH_TRY; + if( !this->_gen_i->isSSLMode() ) + SMESH::throwCorbaException("SMESH_Mesh_i::ExportPartToMEDCoupling : only for embedded mode !"); + + MEDFileMemSpeCls spe; + this->ExportPartToMEDCommon( spe, meshPart, auto_groups, autoDimension, fields, geomAssocFields, + ZTolerance, saveNumbers ); + data = spe.getData(); SMESH_CATCH( SMESH::throwCorbaException ); + + MEDCoupling::DataArrayByte *ret(data.retn()); + return reinterpret_cast(ret); } //================================================================================ @@ -4259,20 +4418,17 @@ void SMESH_Mesh_i::exportMEDFields( DriverMED_W_Field& fieldWriter, */ //================================================================================ -void SMESH_Mesh_i::ExportPartToDAT(::SMESH::SMESH_IDSource_ptr meshPart, - const char* file) +void SMESH_Mesh_i::ExportPartToDAT(SMESH::SMESH_IDSource_ptr meshPart, + const char* file, + CORBA::Boolean renumber ) { SMESH_TRY; - if ( _preMeshInfo ) - _preMeshInfo->FullLoadFromFile(); - - PrepareForWriting(file); SMESH_MeshPartDS partDS( meshPart ); - _impl->ExportDAT(file,&partDS); + _impl->ExportDAT( file, &partDS, renumber ); TPythonDump() << SMESH::SMESH_Mesh_var(_this()) - << ".ExportPartToDAT( " << meshPart << ", r'" << file << "' )"; + << ".ExportPartToDAT( " << meshPart << ", r'" << file << ", " << renumber << "' )"; SMESH_CATCH( SMESH::throwCorbaException ); } @@ -4282,8 +4438,9 @@ void SMESH_Mesh_i::ExportPartToDAT(::SMESH::SMESH_IDSource_ptr meshPart, */ //================================================================================ -void SMESH_Mesh_i::ExportPartToUNV(::SMESH::SMESH_IDSource_ptr meshPart, - const char* file) +void SMESH_Mesh_i::ExportPartToUNV(SMESH::SMESH_IDSource_ptr meshPart, + const char* file, + CORBA::Boolean renumber) { SMESH_TRY; if ( _preMeshInfo ) @@ -4292,10 +4449,10 @@ void SMESH_Mesh_i::ExportPartToUNV(::SMESH::SMESH_IDSource_ptr meshPart, PrepareForWriting(file); SMESH_MeshPartDS partDS( meshPart ); - _impl->ExportUNV(file, &partDS); + _impl->ExportUNV(file, &partDS, renumber ); TPythonDump() << SMESH::SMESH_Mesh_var(_this()) - << ".ExportPartToUNV( " << meshPart<< ", r'" << file << "' )"; + << ".ExportPartToUNV( " << meshPart<< ", r'" << file << ", " << renumber << "' )"; SMESH_CATCH( SMESH::throwCorbaException ); } @@ -5337,7 +5494,7 @@ SMESH::smIdType_array* SMESH_Mesh_i::GetElemNodes(const SMESH::smIdType id) if ( const SMDS_MeshElement* elem = aMeshDS->FindElement(id) ) { aResult->length( elem->NbNodes() ); - for ( SMESH::smIdType i = 0; i < aResult->length(); ++i ) + for ( CORBA::ULong i = 0; i < aResult->length(); ++i ) if ( const SMDS_MeshNode* n = elem->GetNode( i )) aResult[ i ] = n->GetID(); } @@ -5461,7 +5618,7 @@ SMESH::smIdType_array* SMESH_Mesh_i::GetElemFaceNodes(SMESH::smIdType elemId, { aResult->length( vtool.NbFaceNodes( faceIndex )); const SMDS_MeshNode** nn = vtool.GetFaceNodes( faceIndex ); - for ( SMESH::smIdType i = 0; i < aResult->length(); ++i ) + for ( CORBA::ULong i = 0; i < aResult->length(); ++i ) aResult[ i ] = nn[ i ]->GetID(); } } @@ -5544,7 +5701,7 @@ SMESH::smIdType_array* SMESH_Mesh_i::GetElementsByNodes(const SMESH::smIdType_ar if ( SMESHDS_Mesh* mesh = _impl->GetMeshDS() ) { vector< const SMDS_MeshNode * > nn( nodes.length() ); - for ( SMESH::smIdType i = 0; i < nodes.length(); ++i ) + for ( CORBA::ULong i = 0; i < nodes.length(); ++i ) nn[i] = mesh->FindNode( nodes[i] ); std::vector elems; diff --git a/src/SMESH_I/SMESH_Mesh_i.hxx b/src/SMESH_I/SMESH_Mesh_i.hxx index b274e33f6..a2c428656 100644 --- a/src/SMESH_I/SMESH_Mesh_i.hxx +++ b/src/SMESH_I/SMESH_Mesh_i.hxx @@ -212,10 +212,13 @@ public: CORBA::Boolean overwrite, CORBA::Boolean autoDimension = true); + CORBA::LongLong ExportMEDCoupling(CORBA::Boolean auto_groups, + CORBA::Boolean autoDimension = true); + void ExportSAUV( const char* file, CORBA::Boolean auto_groups ); - void ExportDAT( const char* file ); - void ExportUNV( const char* file ); + void ExportDAT( const char* file, const CORBA::Boolean renumber ); + void ExportUNV( const char* file, const CORBA::Boolean renumber ); void ExportSTL( const char* file, bool isascii ); void ExportCGNS(SMESH::SMESH_IDSource_ptr meshPart, const char* file, @@ -225,6 +228,17 @@ public: const char* file, CORBA::Boolean withRequiredGroups); + + template + void ExportPartToMEDCommon(SPECLS& speCls, + SMESH::SMESH_IDSource_ptr meshPart, + CORBA::Boolean auto_groups, + CORBA::Boolean autoDim, + const GEOM::ListOfFields& fields, + const char* geomAssocFields, + CORBA::Double ZTolerance, + CORBA::Boolean saveNumbers ); + void ExportPartToMED(SMESH::SMESH_IDSource_ptr meshPart, const char* file, CORBA::Boolean auto_groups, @@ -233,11 +247,23 @@ public: CORBA::Boolean autoDim, const GEOM::ListOfFields& fields, const char* geomAssocFields, - CORBA::Double ZTolerance); + CORBA::Double ZTolerance, + CORBA::Boolean saveNumbers ); + + CORBA::LongLong ExportPartToMEDCoupling(SMESH::SMESH_IDSource_ptr meshPart, + CORBA::Boolean auto_groups, + CORBA::Boolean autoDim, + const GEOM::ListOfFields& fields, + const char* geomAssocFields, + CORBA::Double ZTolerance, + CORBA::Boolean saveNumbers); + void ExportPartToDAT(SMESH::SMESH_IDSource_ptr meshPart, - const char* file); + const char* file, + CORBA::Boolean renumber); void ExportPartToUNV(SMESH::SMESH_IDSource_ptr meshPart, - const char* file); + const char* file, + CORBA::Boolean renumber); void ExportPartToSTL(SMESH::SMESH_IDSource_ptr meshPart, const char* file, CORBA::Boolean isascii); @@ -626,14 +652,9 @@ public: std::map _mapSubMesh_i; //NRI std::map _mapSubMesh; //NRI -private: +public: + std::string generateMeshName( ); std::string prepareMeshNameAndGroups( const char* file, CORBA::Boolean overwrite ); - - /*! - * Check and correct names of mesh groups - */ - void checkGroupNames(); - /* * Write GEOM fields to MED file */ @@ -641,6 +662,12 @@ private: SMESHDS_Mesh* meshDS, const GEOM::ListOfFields& fields, const char* geomAssocFields); +private: + /*! + * Check and correct names of mesh groups + */ + void checkGroupNames(); + /*! * Convert submesh ids into submesh interfaces */ diff --git a/src/SMESH_I/SMESH_Pattern_i.cxx b/src/SMESH_I/SMESH_Pattern_i.cxx index b5ecf85c9..ab08c61b8 100644 --- a/src/SMESH_I/SMESH_Pattern_i.cxx +++ b/src/SMESH_I/SMESH_Pattern_i.cxx @@ -286,7 +286,7 @@ SMESH::point_array* list xyzList; set fset; - for ( SMESH::smIdType i = 0; i < theFacesIDs.length(); i++) + for ( CORBA::ULong i = 0; i < theFacesIDs.length(); i++) { SMESH::smIdType index = theFacesIDs[i]; const SMDS_MeshElement * elem = aMesh->GetMeshDS()->FindElement(index); @@ -345,7 +345,7 @@ SMESH::point_array* list xyzList; set vset; - for ( SMESH::smIdType i = 0; i < theVolumesIDs.length(); i++) + for ( CORBA::ULong i = 0; i < theVolumesIDs.length(); i++) { SMESH::smIdType index = theVolumesIDs[i]; const SMDS_MeshElement * elem = aMesh->GetMeshDS()->FindElement(index); diff --git a/src/SMESH_I/SMESH_PreMeshInfo.cxx b/src/SMESH_I/SMESH_PreMeshInfo.cxx index 838a77ebe..cb9cdb5d4 100644 --- a/src/SMESH_I/SMESH_PreMeshInfo.cxx +++ b/src/SMESH_I/SMESH_PreMeshInfo.cxx @@ -53,6 +53,8 @@ #include "SMESH_TryCatch.hxx" +#include + #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 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 ); diff --git a/src/SMESH_SWIG/SMESH_mechanic.py b/src/SMESH_SWIG/SMESH_mechanic.py index d79d2c285..0b2974282 100644 --- a/src/SMESH_SWIG/SMESH_mechanic.py +++ b/src/SMESH_SWIG/SMESH_mechanic.py @@ -28,7 +28,7 @@ #------------------------------------------------------------------------- # import salome -salome.salome_init() +salome.salome_init_without_session() import GEOM from salome.geom import geomBuilder geompy = geomBuilder.New() diff --git a/src/SMESH_SWIG/SMESH_mechanic_tetra.py b/src/SMESH_SWIG/SMESH_mechanic_tetra.py index 4cd1d70c8..1e424cbdd 100644 --- a/src/SMESH_SWIG/SMESH_mechanic_tetra.py +++ b/src/SMESH_SWIG/SMESH_mechanic_tetra.py @@ -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() diff --git a/src/SMESH_SWIG/smeshBuilder.py b/src/SMESH_SWIG/smeshBuilder.py index 2c7211828..820e2e1af 100644 --- a/src/SMESH_SWIG/smeshBuilder.py +++ b/src/SMESH_SWIG/smeshBuilder.py @@ -2299,6 +2299,78 @@ class Mesh(metaclass = MeshMeta): self.mesh.RemoveHypothesis( self.geom, hyp ) pass pass + + def ExportMEDCoupling(self, *args, **kwargs): + """ + Export the mesh in a memory representation. + + Parameters: + auto_groups (boolean): parameter for creating/not creating + the groups Group_On_All_Nodes, Group_On_All_Faces, ... ; + the typical use is auto_groups=False. + overwrite (boolean): parameter for overwriting/not overwriting the file + meshPart: a part of mesh (:class:`sub-mesh, group or filter `) + to export instead of the mesh + autoDimension: if *True* (default), a space dimension of a MED mesh can be either + + - 1D if all mesh nodes lie on OX coordinate axis, or + - 2D if all mesh nodes lie on XOY coordinate plane, or + - 3D in the rest cases. + + If *autoDimension* is *False*, the space dimension is always 3. + fields: list of GEOM fields defined on the shape to mesh. + geomAssocFields: each character of this string means a need to export a + corresponding field; correspondence between fields and characters + is following: + + - 'v' stands for "_vertices_" field; + - 'e' stands for "_edges_" field; + - 'f' stands for "_faces_" field; + - 's' stands for "_solids_" field. + + zTolerance (float): tolerance in Z direction. If Z coordinate of a node is + close to zero within a given tolerance, the coordinate is set to zero. + If *ZTolerance* is negative (default), the node coordinates are kept as is. + saveNumbers(boolean) : enable saving numbers of nodes and cells. + """ + auto_groups = args[0] if len(args) > 0 else False + meshPart = args[1] if len(args) > 1 else None + autoDimension = args[2] if len(args) > 2 else True + fields = args[3] if len(args) > 3 else [] + geomAssocFields = args[4] if len(args) > 4 else '' + z_tolerance = args[5] if len(args) > 5 else -1. + saveNumbers = args[6] if len(args) > 6 else True + # process keywords arguments + auto_groups = kwargs.get("auto_groups", auto_groups) + meshPart = kwargs.get("meshPart", meshPart) + autoDimension = kwargs.get("autoDimension", autoDimension) + fields = kwargs.get("fields", fields) + geomAssocFields = kwargs.get("geomAssocFields", geomAssocFields) + z_tolerance = kwargs.get("zTolerance", z_tolerance) + saveNumbers = kwargs.get("saveNumbers", saveNumbers) + + # invoke engine's function + if meshPart or fields or geomAssocFields or z_tolerance > 0 or not saveNumbers: + unRegister = genObjUnRegister() + if isinstance( meshPart, list ): + meshPart = self.GetIDSource( meshPart, SMESH.ALL ) + unRegister.set( meshPart ) + + z_tolerance,Parameters,hasVars = ParseParameters(z_tolerance) + self.mesh.SetParameters(Parameters) + + intPtr = self.mesh.ExportPartToMEDCoupling(meshPart, auto_groups, autoDimension, + fields, geomAssocFields, z_tolerance, + saveNumbers ) + import medcoupling + dab = medcoupling.FromPyIntPtrToDataArrayByte(intPtr) + return medcoupling.MEDFileData.New(dab) + else: + intPtr = self.mesh.ExportMEDCoupling(auto_groups, autoDimension) + import medcoupling + dab = medcoupling.FromPyIntPtrToDataArrayByte(intPtr) + return medcoupling.MEDFileMesh.New(dab) + def ExportMED(self, *args, **kwargs): """ Export the mesh in a file in MED format @@ -2317,7 +2389,8 @@ class Mesh(metaclass = MeshMeta): or 3.2.1 or 3.3.1 formats. If the version is equal to -1, the version is not changed (default). overwrite (boolean): parameter for overwriting/not overwriting the file - meshPart: a part of mesh (:class:`sub-mesh, group or filter `) to export instead of the mesh + meshPart: a part of mesh (:class:`sub-mesh, group or filter `) + to export instead of the mesh autoDimension: if *True* (default), a space dimension of a MED mesh can be either - 1D if all mesh nodes lie on OX coordinate axis, or @@ -2338,6 +2411,7 @@ class Mesh(metaclass = MeshMeta): zTolerance (float): tolerance in Z direction. If Z coordinate of a node is close to zero within a given tolerance, the coordinate is set to zero. If *ZTolerance* is negative (default), the node coordinates are kept as is. + saveNumbers (boolean) : enable saving numbers of nodes and cells. """ # process positional arguments #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]] # backward compatibility @@ -2350,6 +2424,7 @@ class Mesh(metaclass = MeshMeta): fields = args[6] if len(args) > 6 else [] geomAssocFields = args[7] if len(args) > 7 else '' z_tolerance = args[8] if len(args) > 8 else -1. + saveNumbers = args[9] if len(args) > 9 else True # process keywords arguments auto_groups = kwargs.get("auto_groups", auto_groups) version = kwargs.get("version", version) @@ -2360,9 +2435,13 @@ class Mesh(metaclass = MeshMeta): fields = kwargs.get("fields", fields) geomAssocFields = kwargs.get("geomAssocFields", geomAssocFields) z_tolerance = kwargs.get("zTolerance", z_tolerance) + saveNumbers = kwargs.get("saveNumbers", saveNumbers) + + if isinstance( meshPart, Mesh): + meshPart = meshPart.GetMesh() # invoke engine's function - if meshPart or fields or geomAssocFields or z_tolerance > 0: + if meshPart or fields or geomAssocFields or z_tolerance > 0 or not saveNumbers: unRegister = genObjUnRegister() if isinstance( meshPart, list ): meshPart = self.GetIDSource( meshPart, SMESH.ALL ) @@ -2373,7 +2452,7 @@ class Mesh(metaclass = MeshMeta): self.mesh.ExportPartToMED( meshPart, fileName, auto_groups, version, overwrite, autoDimension, - fields, geomAssocFields, z_tolerance) + fields, geomAssocFields, z_tolerance, saveNumbers ) else: self.mesh.ExportMED(fileName, auto_groups, version, overwrite, autoDimension) @@ -2391,41 +2470,43 @@ class Mesh(metaclass = MeshMeta): self.mesh.ExportSAUV(f, auto_groups) - def ExportDAT(self, f, meshPart=None): + def ExportDAT(self, f, meshPart=None, renumber=True): """ Export the mesh in a file in DAT format Parameters: f: the file name meshPart: a part of mesh (:class:`sub-mesh, group or filter `) to export instead of the mesh + renumber(boolean): enable renumbering nodes and cells in order to eliminate holes in numbering """ - if meshPart: + if meshPart or not renumber: unRegister = genObjUnRegister() if isinstance( meshPart, list ): meshPart = self.GetIDSource( meshPart, SMESH.ALL ) unRegister.set( meshPart ) - self.mesh.ExportPartToDAT( meshPart, f ) + self.mesh.ExportPartToDAT( meshPart, f, renumber ) else: - self.mesh.ExportDAT(f) + self.mesh.ExportDAT( f, renumber ) - def ExportUNV(self, f, meshPart=None): + def ExportUNV(self, f, meshPart=None, renumber=True): """ Export the mesh in a file in UNV format Parameters: f: the file name meshPart: a part of mesh (:class:`sub-mesh, group or filter `) to export instead of the mesh + renumber(boolean): enable renumbering nodes and cells in order to eliminate holes in numbering """ - if meshPart: + if meshPart or not renumber: unRegister = genObjUnRegister() if isinstance( meshPart, list ): meshPart = self.GetIDSource( meshPart, SMESH.ALL ) unRegister.set( meshPart ) - self.mesh.ExportPartToUNV( meshPart, f ) + self.mesh.ExportPartToUNV( meshPart, f, renumber ) else: - self.mesh.ExportUNV(f) + self.mesh.ExportUNV( f, renumber ) def ExportSTL(self, f, ascii=1, meshPart=None): """ @@ -7388,6 +7469,14 @@ class meshProxy(SMESH._objref_SMESH_Mesh): while len(args2) < 5: # !!!! nb of parameters for ExportToMED IDL's method args2.append(True) SMESH._objref_SMESH_Mesh.ExportMED(self, *args2) + def ExportUNV(self, *args): # renumber arg added + if len( args ) == 1: + args += True, + return SMESH._objref_SMESH_Mesh.ExportUNV(self, *args) + def ExportDAT(self, *args): # renumber arg added + if len( args ) == 1: + args += True, + return SMESH._objref_SMESH_Mesh.ExportDAT(self, *args) pass omniORB.registerObjref(SMESH._objref_SMESH_Mesh._NP_RepositoryId, meshProxy) diff --git a/src/StdMeshers/CMakeLists.txt b/src/StdMeshers/CMakeLists.txt index 0a69940c1..ec44a6aaf 100644 --- a/src/StdMeshers/CMakeLists.txt +++ b/src/StdMeshers/CMakeLists.txt @@ -29,6 +29,7 @@ INCLUDE_DIRECTORIES( ${Boost_INCLUDE_DIRS} ${KERNEL_INCLUDE_DIRS} ${GEOM_INCLUDE_DIRS} + ${MEDCOUPLING_INCLUDE_DIRS} ${PROJECT_SOURCE_DIR}/src/SMESHUtils ${PROJECT_SOURCE_DIR}/src/SMESH ${PROJECT_SOURCE_DIR}/src/SMESHDS diff --git a/src/StdMeshers/StdMeshers_BlockRenumber.cxx b/src/StdMeshers/StdMeshers_BlockRenumber.cxx index 9dea567d4..df74a1665 100644 --- a/src/StdMeshers/StdMeshers_BlockRenumber.cxx +++ b/src/StdMeshers/StdMeshers_BlockRenumber.cxx @@ -26,14 +26,15 @@ #include "StdMeshers_BlockRenumber.hxx" -#include "SMDS_EdgePosition.hxx" -#include "SMDS_FacePosition.hxx" -#include "SMESHDS_Mesh.hxx" -#include "SMESHDS_SubMesh.hxx" -#include "SMESH_Algo.hxx" -#include "SMESH_Mesh.hxx" -#include "SMESH_MesherHelper.hxx" -#include "SMESH_TryCatch.hxx" +#include +#include +#include +#include +#include +#include +#include +#include +#include #include #include @@ -41,7 +42,6 @@ #include #include -#include //============================================================================= /*! @@ -203,11 +203,11 @@ TopoDS_Vertex StdMeshers_RenumberHelper::GetVertex000( const TopTools_MapOfShape } //======================================================================= -//function : GetVertex000 -//purpose : Find default vertex at (0,0,0) local position +//function : GetVertexAtPoint +//purpose : Return the VERTEX of solid at given point //======================================================================= -TopoDS_Vertex StdMeshers_RenumberHelper::GetVertexAtPoint( const TopoDS_Shape& solid, +TopoDS_Vertex StdMeshers_RenumberHelper::GetVertexAtPoint( const TopoDS_Shape& solid, const TopoDS_Shape& point ) { if ( !solid.IsNull() && !point.IsNull() && point.ShapeType() == TopAbs_VERTEX ) @@ -296,8 +296,7 @@ istream & StdMeshers_BlockRenumber::LoadFrom(istream & load) { SMESH_TRY; - boost::archive::text_iarchive archive( load ); - archive >> *this; + SMESHUtils::BoostTxtArchive( load ) >> *this; SMESH_CATCH( SMESH::doNothing ); diff --git a/src/StdMeshers/StdMeshers_Cartesian_3D.cxx b/src/StdMeshers/StdMeshers_Cartesian_3D.cxx index 2b28bc3ce..dc82aa09a 100644 --- a/src/StdMeshers/StdMeshers_Cartesian_3D.cxx +++ b/src/StdMeshers/StdMeshers_Cartesian_3D.cxx @@ -79,6 +79,7 @@ #include #include #include +#include #include #include #include @@ -97,7 +98,11 @@ #include -//#undef WITH_TBB +#ifdef _DEBUG_ +// #define _MY_DEBUG_ +// #undef WITH_TBB +#endif + #ifdef WITH_TBB #ifdef WIN32 @@ -114,10 +119,6 @@ using namespace std; using namespace SMESH; -#ifdef _DEBUG_ -//#define _MY_DEBUG_ -#endif - //============================================================================= /*! * Constructor @@ -171,6 +172,8 @@ namespace { typedef int TGeomID; // IDs of sub-shapes + const TGeomID theUndefID = 1e+9; + //============================================================================= // Definitions of internal utils // -------------------------------------------------------------------------- @@ -182,13 +185,33 @@ namespace Trans_INTERNAL // for INTERNAL FACE }; // -------------------------------------------------------------------------- + /*! + * \brief Sub-entities of a FACE neighboring its concave VERTEX. + * Help to avoid linking nodes on EDGEs that seem connected + * by the concave FACE but the link actually lies outside the FACE + */ + struct ConcaveFace + { + TGeomID _concaveFace; + TGeomID _edge1, _edge2; + TGeomID _v1, _v2; + ConcaveFace( int f=0, int e1=0, int e2=0, int v1=0, int v2=0 ) + : _concaveFace(f), _edge1(e1), _edge2(e2), _v1(v1), _v2(v2) {} + bool HasEdge( TGeomID edge ) const { return edge == _edge1 || edge == _edge2; } + bool HasVertex( TGeomID v ) const { return v == _v1 || v == _v2; } + void SetEdge( TGeomID edge ) { ( _edge1 ? _edge2 : _edge1 ) = edge; } + void SetVertex( TGeomID v ) { ( _v1 ? _v2 : _v1 ) = v; } + }; + typedef NCollection_DataMap< TGeomID, ConcaveFace > TConcaveVertex2Face; + // -------------------------------------------------------------------------- /*! * \brief Container of IDs of SOLID sub-shapes */ class Solid // sole SOLID contains all sub-shapes { - TGeomID _id; // SOLID id - bool _hasInternalFaces; + TGeomID _id; // SOLID id + bool _hasInternalFaces; + TConcaveVertex2Face _concaveVertex; // concave VERTEX -> ConcaveFace public: virtual ~Solid() {} virtual bool Contains( TGeomID /*subID*/ ) const { return true; } @@ -199,6 +222,10 @@ namespace TGeomID ID() const { return _id; } void SetHasInternalFaces( bool has ) { _hasInternalFaces = has; } bool HasInternalFaces() const { return _hasInternalFaces; } + void SetConcave( TGeomID V, TGeomID F, TGeomID E1, TGeomID E2, TGeomID V1, TGeomID V2 ) + { _concaveVertex.Bind( V, ConcaveFace{ F, E1, E2, V1, V2 }); } + bool HasConcaveVertex() const { return !_concaveVertex.IsEmpty(); } + const ConcaveFace* GetConcave( TGeomID V ) const { return _concaveVertex.Seek( V ); } }; // -------------------------------------------------------------------------- class OneOfSolids : public Solid @@ -227,6 +254,47 @@ namespace } }; // -------------------------------------------------------------------------- + /*! + * \brief Hold a vector of TGeomID and clear it at destruction + */ + class GeomIDVecHelder + { + typedef std::vector< TGeomID > TVector; + const TVector& myVec; + bool myOwn; + + public: + GeomIDVecHelder( const TVector& idVec, bool isOwner ): myVec( idVec ), myOwn( isOwner ) {} + GeomIDVecHelder( const GeomIDVecHelder& holder ): myVec( holder.myVec ), myOwn( holder.myOwn ) + { + const_cast< bool& >( holder.myOwn ) = false; + } + ~GeomIDVecHelder() { if ( myOwn ) const_cast( myVec ).clear(); } + size_t size() const { return myVec.size(); } + TGeomID operator[]( size_t i ) const { return i < size() ? myVec[i] : theUndefID; } + bool operator==( const GeomIDVecHelder& other ) const { return myVec == other.myVec; } + bool contain( const TGeomID& id ) const { + return std::find( myVec.begin(), myVec.end(), id ) != myVec.end(); + } + TGeomID otherThan( const TGeomID& id ) const { + for ( const TGeomID& id2 : myVec ) + if ( id != id2 ) + return id2; + return theUndefID; + } + TGeomID oneCommon( const GeomIDVecHelder& other ) const { + TGeomID common = theUndefID; + for ( const TGeomID& id : myVec ) + if ( other.contain( id )) + { + if ( common != theUndefID ) + return theUndefID; + common = id; + } + return common; + } + }; + // -------------------------------------------------------------------------- /*! * \brief Geom data */ @@ -240,10 +308,13 @@ namespace TColStd_MapOfInteger _strangeEdges; // EDGEs shared by strange FACEs TGeomID _extIntFaceID; // pseudo FACE - extension of INTERNAL FACE + TopTools_DataMapOfShapeInteger _shape2NbNodes; // nb of pre-existing nodes on shapes + Controls::ElementsOnShape _edgeClassifier; Controls::ElementsOnShape _vertexClassifier; bool IsOneSolid() const { return _solidByID.size() < 2; } + GeomIDVecHelder GetSolidIDsByShapeID( const vector< TGeomID >& shapeIDs ) const; }; // -------------------------------------------------------------------------- /*! @@ -255,9 +326,10 @@ namespace mutable vector< TGeomID > _faceIDs; B_IntersectPoint(): _node(NULL) {} - void Add( const vector< TGeomID >& fIDs, const SMDS_MeshNode* n=0 ) const; - int HasCommonFace( const B_IntersectPoint * other, int avoidFace=-1 ) const; - bool IsOnFace( int faceID ) const; + bool Add( const vector< TGeomID >& fIDs, const SMDS_MeshNode* n=0 ) const; + TGeomID HasCommonFace( const B_IntersectPoint * other, TGeomID avoidFace=-1 ) const; + size_t GetCommonFaces( const B_IntersectPoint * other, TGeomID * commonFaces ) const; + bool IsOnFace( TGeomID faceID ) const; virtual ~B_IntersectPoint() {} }; // -------------------------------------------------------------------------- @@ -428,7 +500,9 @@ namespace const vector< TGeomID > & GetSolidIDs( TGeomID subShapeID ) const; bool IsCorrectTransition( TGeomID faceID, const Solid* solid ); bool IsBoundaryFace( TGeomID face ) const { return _geometry._boundaryFaces.Contains( face ); } - void SetOnShape( const SMDS_MeshNode* n, const F_IntersectPoint& ip, bool unset=false ); + void SetOnShape( const SMDS_MeshNode* n, const F_IntersectPoint& ip, + TopoDS_Vertex* vertex = nullptr, bool unset = false ); + void UpdateFacesOfVertex( const B_IntersectPoint& ip, const TopoDS_Vertex& vertex ); bool IsToCheckNodePos() const { return !_toAddEdges && _toCreateFaces; } bool IsToRemoveExcessEntities() const { return !_toAddEdges; } @@ -610,6 +684,10 @@ namespace { return _intPoint ? _intPoint->IsOnFace( faceID ) : false; } + size_t GetCommonFaces( const B_IntersectPoint * other, TGeomID* common ) const + { + return _intPoint && other ? _intPoint->GetCommonFaces( other, common ) : 0; + } gp_Pnt Point() const { if ( const SMDS_MeshNode* n = Node() ) @@ -664,7 +742,7 @@ namespace bool _reverse; _OrientedLink( _Link* link=0, bool reverse=false ): _link(link), _reverse(reverse) {} void Reverse() { _reverse = !_reverse; } - int NbResultLinks() const { return _link->_splits.size(); } + size_t NbResultLinks() const { return _link->_splits.size(); } _OrientedLink ResultLink(int i) const { return _OrientedLink(&_link->_splits[_reverse ? NbResultLinks()-i-1 : i],_reverse); @@ -818,21 +896,22 @@ namespace }; vector< _nodeDef > _nodes; - vector< int > _quantities; + vector< int > _quantities; _volumeDef* _next; // to store several _volumeDefs in a chain TGeomID _solidID; + double _size; const SMDS_MeshElement* _volume; // new volume vector< SMESH_Block::TShapeID > _names; // name of side a polygon originates from - _volumeDef(): _next(0), _solidID(0), _volume(0) {} + _volumeDef(): _next(0), _solidID(0), _size(0), _volume(0) {} ~_volumeDef() { delete _next; } _volumeDef( _volumeDef& other ): - _next(0), _solidID( other._solidID ), _volume( other._volume ) + _next(0), _solidID( other._solidID ), _size( other._size ), _volume( other._volume ) { _nodes.swap( other._nodes ); _quantities.swap( other._quantities ); other._volume = 0; _names.swap( other._names ); } - size_t size() const { return 1 + ( _next ? _next->size() : 0 ); } + size_t size() const { return 1 + ( _next ? _next->size() : 0 ); } // nb _volumeDef in a chain _volumeDef* at(int index) { return index == 0 ? this : ( _next ? _next->at(index-1) : _next ); } @@ -927,11 +1006,13 @@ namespace bool addIntersection( const E_IntersectPoint* ip, vector< Hexahedron* >& hexes, int ijk[], int dIJK[] ); + bool isQuadOnFace( const size_t iQuad ); bool findChain( _Node* n1, _Node* n2, _Face& quad, vector<_Node*>& chainNodes ); bool closePolygon( _Face* polygon, vector<_Node*>& chainNodes ) const; bool findChainOnEdge( const vector< _OrientedLink >& splits, const _OrientedLink& prevSplit, const _OrientedLink& avoidSplit, + const std::set< TGeomID > & concaveFaces, size_t & iS, _Face& quad, vector<_Node*>& chn); @@ -953,7 +1034,7 @@ namespace void sortVertexNodes(vector<_Node*>& nodes, _Node* curNode, TGeomID face); bool isInHole() const; bool hasStrangeEdge() const; - bool checkPolyhedronSize( bool isCutByInternalFace ) const; + bool checkPolyhedronSize( bool isCutByInternalFace, double & volSize ) const; bool addHexa (); bool addTetra(); bool addPenta(); @@ -969,6 +1050,9 @@ namespace return nodes[i]; return 0; } + bool isCorner( const _Node* node ) const { return ( node >= &_hexNodes[0] && + node - &_hexNodes[0] < 8 ); } + bool hasEdgesAround( const ConcaveFace* cf ) const; bool isImplementEdges() const { return _grid->_edgeIntPool.nbElements(); } bool isOutParam(const double uvw[3]) const; @@ -1039,6 +1123,32 @@ namespace di = 0; } //============================================================================= + /* + * Return a vector of SOLIDS sharing given shapes + */ + GeomIDVecHelder Geometry::GetSolidIDsByShapeID( const vector< TGeomID >& theShapeIDs ) const + { + if ( theShapeIDs.size() == 1 ) + return GeomIDVecHelder( _solidIDsByShapeID[ theShapeIDs[ 0 ]], /*owner=*/false ); + + // look for an empty slot in _solidIDsByShapeID + vector< TGeomID > * resultIDs = 0; + for ( const vector< TGeomID >& vec : _solidIDsByShapeID ) + if ( vec.empty() ) + { + resultIDs = const_cast< vector< TGeomID > * >( & vec ); + break; + } + // fill in resultIDs + for ( const TGeomID& id : theShapeIDs ) + for ( const TGeomID& solid : _solidIDsByShapeID[ id ]) + { + if ( std::find( resultIDs->begin(), resultIDs->end(), solid ) == resultIDs->end() ) + resultIDs->push_back( solid ); + } + return GeomIDVecHelder( *resultIDs, /*owner=*/true ); + } + //============================================================================= /* * Remove coincident intersection points */ @@ -1111,42 +1221,47 @@ namespace return isOut ? 0 : geom._soleSolid.ID(); } - const vector< TGeomID >& solids = geom._solidIDsByShapeID[ ip->_faceIDs[ 0 ]]; + GeomIDVecHelder solids = geom.GetSolidIDsByShapeID( ip->_faceIDs ); --ip; if ( ip->_transition == Trans_INTERNAL ) return prevID; - const vector< TGeomID >& solidsBef = geom._solidIDsByShapeID[ ip->_faceIDs[ 0 ]]; + GeomIDVecHelder solidsBef = geom.GetSolidIDsByShapeID( ip->_faceIDs ); if ( ip->_transition == Trans_IN || ip->_transition == Trans_OUT ) { if ( solidsBef.size() == 1 ) - return ( solidsBef[0] == prevID ) ? 0 : solidsBef[0]; + { + if ( solidsBef[0] == prevID ) + return ip->_transition == Trans_OUT ? 0 : solidsBef[0]; + else + return solidsBef[0]; + } - return solidsBef[ solidsBef[0] == prevID ]; + if ( solids.size() == 2 ) + { + if ( solids == solidsBef ) + return theUndefID; //solids.contain( prevID ) ? solids.otherThan( prevID ) : theUndefID; + } + return solids.oneCommon( solidsBef ); } if ( solidsBef.size() == 1 ) return solidsBef[0]; - for ( size_t i = 0; i < solids.size(); ++i ) - { - vector< TGeomID >::const_iterator it = - std::find( solidsBef.begin(), solidsBef.end(), solids[i] ); - if ( it != solidsBef.end() ) - return solids[i]; - } - return 0; + return solids.oneCommon( solidsBef ); } //================================================================================ /* * Adds face IDs */ - void B_IntersectPoint::Add( const vector< TGeomID >& fIDs, + bool B_IntersectPoint::Add( const vector< TGeomID >& fIDs, const SMDS_MeshNode* n) const { + size_t prevNbF = _faceIDs.size(); + if ( _faceIDs.empty() ) _faceIDs = fIDs; else @@ -1159,12 +1274,14 @@ namespace } if ( !_node ) _node = n; + + return prevNbF < _faceIDs.size(); } //================================================================================ /* - * Returns index of a common face if any, else zero + * Return ID of a common face if any, else zero */ - int B_IntersectPoint::HasCommonFace( const B_IntersectPoint * other, int avoidFace ) const + TGeomID B_IntersectPoint::HasCommonFace( const B_IntersectPoint * other, TGeomID avoidFace ) const { if ( other ) for ( size_t i = 0; i < other->_faceIDs.size(); ++i ) @@ -1175,9 +1292,25 @@ namespace } //================================================================================ /* - * Returns \c true if \a faceID in in this->_faceIDs + * Return faces common with other point */ - bool B_IntersectPoint::IsOnFace( int faceID ) const // returns true if faceID is found + size_t B_IntersectPoint::GetCommonFaces( const B_IntersectPoint * other, TGeomID* common ) const + { + size_t nbComm = 0; + if ( !other ) + return nbComm; + if ( _faceIDs.size() > other->_faceIDs.size() ) + return other->GetCommonFaces( this, common ); + for ( const TGeomID& face : _faceIDs ) + if ( other->IsOnFace( face )) + common[ nbComm++ ] = face; + return nbComm; + } + //================================================================================ + /* + * Return \c true if \a faceID in in this->_faceIDs + */ + bool B_IntersectPoint::IsOnFace( TGeomID faceID ) const // returns true if faceID is found { vector< TGeomID >::const_iterator it = std::find( _faceIDs.begin(), _faceIDs.end(), faceID ); @@ -1392,8 +1525,7 @@ namespace } TopTools_IndexedMapOfShape faces; - if ( _toCreateFaces || isSeveralSolids ) - TopExp::MapShapes( theShapeToMesh, TopAbs_FACE, faces ); + TopExp::MapShapes( theShapeToMesh, TopAbs_FACE, faces ); // find boundary FACEs on boundary of mesh->ShapeToMesh() if ( _toCreateFaces ) @@ -1416,6 +1548,62 @@ namespace SetSolidFather( _helper->IthVertex( 1, edge ), theShapeToMesh ); } } + + // fill in _geometry._shape2NbNodes == find already meshed sub-shapes + _geometry._shape2NbNodes.Clear(); + if ( mesh->NbNodes() > 0 ) + { + for ( TopAbs_ShapeEnum type : { TopAbs_FACE, TopAbs_EDGE, TopAbs_VERTEX }) + for ( TopExp_Explorer exp( theShapeToMesh, type ); exp.More(); exp.Next() ) + { + if ( _geometry._shape2NbNodes.IsBound( exp.Current() )) + continue; + if ( SMESHDS_SubMesh* sm = mesh->GetMeshDS()->MeshElements( exp.Current() )) + if ( sm->NbNodes() > 0 ) + _geometry._shape2NbNodes.Bind( exp.Current(), sm->NbNodes() ); + } + } + + // fill in Solid::_concaveVertex + vector< TGeomID > soleSolidID( 1, _geometry._soleSolid.ID() ); + for ( int i = 1; i <= faces.Size(); ++i ) + { + const TopoDS_Face& F = TopoDS::Face( faces( i )); + TError error; + TSideVector wires = StdMeshers_FaceSide::GetFaceWires( F, *mesh, 0, error, + nullptr, nullptr, false ); + for ( StdMeshers_FaceSidePtr& wire : wires ) + { + const int nbEdges = wire->NbEdges(); + if ( nbEdges < 2 && SMESH_Algo::isDegenerated( wire->Edge(0))) + continue; + for ( int iE1 = 0; iE1 < nbEdges; ++iE1 ) + { + if ( SMESH_Algo::isDegenerated( wire->Edge( iE1 ))) continue; + int iE2 = ( iE1 + 1 ) % nbEdges; + while ( SMESH_Algo::isDegenerated( wire->Edge( iE2 ))) + iE2 = ( iE2 + 1 ) % nbEdges; + TopoDS_Vertex V = wire->FirstVertex( iE2 ); + double angle = _helper->GetAngle( wire->Edge( iE1 ), + wire->Edge( iE2 ), F, V ); + if ( angle < -5. * M_PI / 180. ) + { + TGeomID faceID = ShapeID( F ); + const vector< TGeomID > & solids = + _geometry.IsOneSolid() ? soleSolidID : GetSolidIDs( faceID ); + for ( const TGeomID & solidID : solids ) + { + Solid* solid = GetSolid( solidID ); + TGeomID V1 = ShapeID( wire->FirstVertex( iE1 )); + TGeomID V2 = ShapeID( wire->LastVertex ( iE2 )); + solid->SetConcave( ShapeID( V ), faceID, + wire->EdgeID( iE1 ), wire->EdgeID( iE2 ), V1, V2 ); + } + } + } + } + } + return; } //================================================================================ @@ -1504,8 +1692,10 @@ namespace //================================================================================ /* * Assign to geometry a node at FACE intersection + * Return a found supporting VERTEX */ - void Grid::SetOnShape( const SMDS_MeshNode* n, const F_IntersectPoint& ip, bool unset ) + void Grid::SetOnShape( const SMDS_MeshNode* n, const F_IntersectPoint& ip, + TopoDS_Vertex* vertex, bool unset ) { TopoDS_Shape s; SMESHDS_Mesh* mesh = _helper->GetMeshDS(); @@ -1517,6 +1707,8 @@ namespace { if ( unset ) mesh->UnSetNodeOnShape( n ); mesh->SetNodeOnVertex( n, TopoDS::Vertex( s )); + if ( vertex ) + *vertex = TopoDS::Vertex( s ); } else if ( _geometry._edgeClassifier.IsSatisfy( n, &s )) { @@ -1533,6 +1725,23 @@ namespace } } //================================================================================ + /* + * Fill in B_IntersectPoint::_faceIDs with all FACEs sharing a VERTEX + */ + void Grid::UpdateFacesOfVertex( const B_IntersectPoint& ip, const TopoDS_Vertex& vertex ) + { + if ( vertex.IsNull() ) + return; + std::vector< int > faceID(1); + PShapeIteratorPtr fIt = _helper->GetAncestors( vertex, *_helper->GetMesh(), + TopAbs_FACE, & _geometry._mainShape ); + while ( const TopoDS_Shape* face = fIt->next() ) + { + faceID[ 0 ] = ShapeID( *face ); + ip.Add( faceID ); + } + } + //================================================================================ /* * Initialize a classifier */ @@ -1618,8 +1827,7 @@ namespace { // state of each node of the grid relative to the geometry const size_t nbGridNodes = _coords[0].size() * _coords[1].size() * _coords[2].size(); - const TGeomID undefID = 1e+9; - vector< TGeomID > shapeIDVec( nbGridNodes, undefID ); + vector< TGeomID > shapeIDVec( nbGridNodes, theUndefID ); _nodes.resize( nbGridNodes, 0 ); _gridIntP.resize( nbGridNodes, NULL ); @@ -1681,7 +1889,9 @@ namespace gp_XYZ xyz = lineLoc + ip->_paramOnLine * lineDir; ip->_node = mesh->AddNode( xyz.X(), xyz.Y(), xyz.Z() ); ip->_indexOnLine = nodeCoord-coord0-1; - SetOnShape( ip->_node, *ip ); + TopoDS_Vertex v; + SetOnShape( ip->_node, *ip, & v ); + UpdateFacesOfVertex( *ip, v ); } // create a mesh node at ip coincident with a grid node else @@ -1718,7 +1928,7 @@ namespace { size_t nodeIndex = NodeIndex( x, y, z ); if ( !_nodes[ nodeIndex ] && - 0 < shapeIDVec[ nodeIndex ] && shapeIDVec[ nodeIndex ] < undefID ) + 0 < shapeIDVec[ nodeIndex ] && shapeIDVec[ nodeIndex ] < theUndefID ) { gp_XYZ xyz = ( _coords[0][x] * _axes[0] + _coords[1][y] * _axes[1] + @@ -1729,7 +1939,9 @@ namespace else if ( _nodes[ nodeIndex ] && _gridIntP[ nodeIndex ] /*&& !_nodes[ nodeIndex]->GetShapeID()*/ ) { - SetOnShape( _nodes[ nodeIndex ], *_gridIntP[ nodeIndex ]); + TopoDS_Vertex v; + SetOnShape( _nodes[ nodeIndex ], *_gridIntP[ nodeIndex ], & v ); + UpdateFacesOfVertex( *_gridIntP[ nodeIndex ], v ); } } @@ -2694,6 +2906,26 @@ namespace if ( intFlag & IS_CUT_BY_INTERNAL_FACE && !_grid->_toAddEdges ) // Issue #19913 preventVolumesOverlapping(); + std::set< TGeomID > concaveFaces; // to avoid connecting nodes laying on them + + if ( solid->HasConcaveVertex() ) + { + for ( const E_IntersectPoint* ip : _eIntPoints ) + { + if ( const ConcaveFace* cf = solid->GetConcave( ip->_shapeID )) + if ( this->hasEdgesAround( cf )) + concaveFaces.insert( cf->_concaveFace ); + } + if ( concaveFaces.empty() || concaveFaces.size() * 3 < _eIntPoints.size() ) + for ( const _Node& hexNode: _hexNodes ) + { + if ( hexNode._node && hexNode._intPoint && hexNode._intPoint->_faceIDs.size() >= 3 ) + if ( const ConcaveFace* cf = solid->GetConcave( hexNode._node->GetShapeID() )) + if ( this->hasEdgesAround( cf )) + concaveFaces.insert( cf->_concaveFace ); + } + } + // Create polygons from quadrangles // -------------------------------- @@ -2715,9 +2947,16 @@ namespace splits.clear(); for ( int iE = 0; iE < 4; ++iE ) // loop on 4 sides of a quadrangle - for ( int iS = 0; iS < quad._links[ iE ].NbResultLinks(); ++iS ) + for ( size_t iS = 0; iS < quad._links[ iE ].NbResultLinks(); ++iS ) splits.push_back( quad._links[ iE ].ResultLink( iS )); + if ( splits.size() == 4 && + isQuadOnFace( iF )) // check if a quad on FACE is not split + { + polygon->_links.swap( splits ); + continue; // goto the next quad + } + // add splits of links to a polygon and add _polyLinks to make // polygon's boundary closed @@ -2766,7 +3005,8 @@ namespace ( n1->_isInternalFlags ))) { // n1 is at intersection with EDGE - if ( findChainOnEdge( splits, polygon->_links.back(), split, iS, quad, chainNodes )) + if ( findChainOnEdge( splits, polygon->_links.back(), split, concaveFaces, + iS, quad, chainNodes )) { for ( size_t i = 1; i < chainNodes.size(); ++i ) polygon->AddPolyLink( chainNodes[i-1], chainNodes[i], prevPolyg ); @@ -2914,11 +3154,12 @@ namespace } } - set usedFaceIDs; - vector< TGeomID > faces; + std::set usedFaceIDs; + std::vector< TGeomID > faces; TGeomID curFace = 0; const size_t nbQuadPolygons = _polygons.size(); E_IntersectPoint ipTmp; + std::map< TGeomID, std::vector< const B_IntersectPoint* > > tmpAddedFace; // face added to _intPoint // create polygons by making closed chains of free links size_t iPolygon = _polygons.size(); @@ -3082,7 +3323,10 @@ namespace if ( polygon._links.size() < 2 || polygon._links[0].LastNode() != polygon._links.back().FirstNode() ) - return false; // closed polygon not found -> invalid polyhedron + { + _polygons.clear(); + break; // closed polygon not found -> invalid polyhedron + } if ( polygon._links.size() == 2 ) { @@ -3177,8 +3421,11 @@ namespace for ( int iN = 0; iN < 2; ++iN ) { _Node* n = freeLinks[ iL3 ]->_link->_nodes[ iN ]; - if ( n->_intPoint ) n->_intPoint->Add( ipTmp._faceIDs ); - else n->_intPoint = &ipTmp; + bool added = false; + if ( n->_intPoint ) added = n->_intPoint->Add( ipTmp._faceIDs ); + else n->_intPoint = &ipTmp; + if ( added ) + tmpAddedFace[ ipTmp._faceIDs[0] ].push_back( n->_intPoint ); } break; } @@ -3203,8 +3450,23 @@ namespace } // end of case ( polygon._links.size() > 2 ) } // while ( nbFreeLinks > 0 ) + for ( auto & face_ip : tmpAddedFace ) + { + curFace = face_ip.first; + for ( const B_IntersectPoint* ip : face_ip.second ) + { + auto it = std::find( ip->_faceIDs.begin(), ip->_faceIDs.end(), curFace ); + if ( it != ip->_faceIDs.end() ) + ip->_faceIDs.erase( it ); + } + } + + if ( _polygons.size() < 3 ) + return false; + // check volume size - _hasTooSmall = ! checkPolyhedronSize( intFlag & IS_CUT_BY_INTERNAL_FACE ); + double volSize = 0; + _hasTooSmall = ! checkPolyhedronSize( intFlag & IS_CUT_BY_INTERNAL_FACE, volSize ); for ( size_t i = 0; i < 8; ++i ) if ( _hexNodes[ i ]._intPoint == &ipTmp ) @@ -3251,7 +3513,7 @@ namespace int nbPolygons = 0; for ( size_t iF = 0; iF < _polygons.size(); ++iF ) - nbPolygons += (_polygons[ iF ]._links.size() > 0 ); + nbPolygons += (_polygons[ iF ]._links.size() > 2 ); //const int nbNodes = _nbCornerNodes + nbIntersections; int nbNodes = 0; @@ -3270,7 +3532,7 @@ namespace for ( size_t iF = 0; iF < _polygons.size(); ++iF ) { const size_t nbLinks = _polygons[ iF ]._links.size(); - if ( nbLinks == 0 ) continue; + if ( nbLinks < 3 ) continue; _volumeDefs._quantities.push_back( nbLinks ); _volumeDefs._names.push_back( _polygons[ iF ]._name ); for ( size_t iL = 0; iL < nbLinks; ++iL ) @@ -3278,6 +3540,7 @@ namespace } } _volumeDefs._solidID = solid->ID(); + _volumeDefs._size = volSize; return !_volumeDefs._nodes.empty(); } @@ -3386,7 +3649,7 @@ namespace } else if ( _nbCornerNodes > 3 && !hex ) { - // all intersection of hex with geometry are at grid nodes + // all intersections of hex with geometry are at grid nodes hex = new Hexahedron( *this, _i, _j, _k, i ); intHexa.push_back( hex ); } @@ -3428,6 +3691,22 @@ namespace hex->getBoundaryElems( boundaryVolumes ); } + // merge nodes on outer sub-shapes with pre-existing ones + TopTools_DataMapIteratorOfDataMapOfShapeInteger s2nIt( _grid->_geometry._shape2NbNodes ); + for ( ; s2nIt.More(); s2nIt.Next() ) + if ( s2nIt.Value() > 0 ) + if ( SMESHDS_SubMesh* sm = mesh->MeshElements( s2nIt.Key() )) + { + TIDSortedNodeSet smNodes( SMDS_MeshElement::iterator( sm->GetNodes() ), + SMDS_MeshElement::iterator() ); + SMESH_MeshEditor::TListOfListOfNodes equalNodes; + SMESH_MeshEditor editor( helper.GetMesh() ); + editor.FindCoincidentNodes( smNodes, 10 * _grid->_tol, equalNodes, + /*SeparateCornersAndMedium =*/ false); + if ((int) equalNodes.size() <= s2nIt.Value() ) + editor.MergeNodes( equalNodes ); + } + // create boundary mesh faces addFaces( helper, boundaryVolumes ); @@ -3541,6 +3820,7 @@ namespace ip._point = p1; ip._shapeID = _grid->ShapeID( v1 ); vip = _grid->Add( ip ); + _grid->UpdateFacesOfVertex( *vip, v1 ); if ( isInternal ) vip->_faceIDs.push_back( _grid->PseudoIntExtFaceID() ); if ( !addIntersection( vip, hexes, ijk, d000 )) @@ -3601,9 +3881,12 @@ namespace ijk[ iDirZ ] = iZ1; bool sameV = ( v1.IsSame( v2 )); if ( !sameV ) + { vip = _grid->Add( ip ); - if ( isInternal && !sameV ) - vip->_faceIDs.push_back( _grid->PseudoIntExtFaceID() ); + _grid->UpdateFacesOfVertex( *vip, v2 ); + if ( isInternal ) + vip->_faceIDs.push_back( _grid->PseudoIntExtFaceID() ); + } if ( !addIntersection( vip, hexes, ijk, d000 ) && !sameV ) _grid->Remove( vip ); ip._shapeID = edgeID; @@ -3976,6 +4259,55 @@ namespace return added; } //================================================================================ + /*! + * \brief Check if a hexahedron facet lies on a FACE + * Also return true if the facet does not interfere with any FACE + */ + bool Hexahedron::isQuadOnFace( const size_t iQuad ) + { + _Face& quad = _hexQuads[ iQuad ] ; + + int nbGridNodesInt = 0; // nb FACE intersections at grid nodes + int nbNoGeomNodes = 0; + for ( int iE = 0; iE < 4; ++iE ) + { + nbNoGeomNodes = ( !quad._links[ iE ].FirstNode()->_intPoint && + quad._links[ iE ].NbResultLinks() == 1 ); + nbGridNodesInt += + ( quad._links[ iE ].FirstNode()->_intPoint && + quad._links[ iE ].NbResultLinks() == 1 && + quad._links[ iE ].ResultLink( 0 ).FirstNode() == quad._links[ iE ].FirstNode() && + quad._links[ iE ].ResultLink( 0 ).LastNode() == quad._links[ iE ].LastNode() ); + } + if ( nbNoGeomNodes == 4 ) + return true; + + if ( nbGridNodesInt == 4 ) // all quad nodes are at FACE intersection + { + size_t iEmin = 0, minNbFaces = 1000; + for ( int iE = 0; iE < 4; ++iE ) // look for a node with min nb FACEs + { + size_t nbFaces = quad._links[ iE ].FirstNode()->faces().size(); + if ( minNbFaces > nbFaces ) + { + iEmin = iE; + minNbFaces = nbFaces; + } + } + // check if there is a FACE passing through all 4 nodes + for ( const TGeomID& faceID : quad._links[ iEmin ].FirstNode()->faces() ) + { + bool allNodesAtFace = true; + for ( size_t iE = 0; iE < 4 && allNodesAtFace; ++iE ) + allNodesAtFace = ( iE == iEmin || + quad._links[ iE ].FirstNode()->IsOnFace( faceID )); + if ( allNodesAtFace ) // quad if on faceID + return true; + } + } + return false; + } + //================================================================================ /*! * \brief Finds nodes at a path from one node to another via intersections with EDGEs */ @@ -4026,8 +4358,8 @@ namespace return false; vector< _OrientedLink > newLinks; // find a node lying on the same FACE as the last one - _Node* node = polygon->_links.back().LastNode(); - int avoidFace = node->IsLinked( polygon->_links.back().FirstNode()->_intPoint ); + _Node* node = polygon->_links.back().LastNode(); + TGeomID avoidFace = node->IsLinked( polygon->_links.back().FirstNode()->_intPoint ); for ( i = nbLinks - 2; i >= 0; --i ) if ( node->IsLinked( polygon->_links[i].FirstNode()->_intPoint, avoidFace )) break; @@ -4070,19 +4402,20 @@ namespace bool Hexahedron::findChainOnEdge( const vector< _OrientedLink >& splits, const _OrientedLink& prevSplit, const _OrientedLink& avoidSplit, + const std::set< TGeomID > & concaveFaces, size_t & iS, _Face& quad, vector<_Node*>& chn ) { _Node* pn1 = prevSplit.FirstNode(); - _Node* pn2 = prevSplit.LastNode(); - int avoidFace = pn1->IsLinked( pn2->_intPoint ); // FACE under the quad + _Node* pn2 = prevSplit.LastNode(); // pn2 is on EDGE, if not on INTERNAL FACE + _Node* an3 = avoidSplit.LastNode(); + TGeomID avoidFace = pn1->IsLinked( pn2->_intPoint ); // FACE under the quad if ( avoidFace < 1 && pn1->_intPoint ) return false; - _Node* n = 0, *stopNode = avoidSplit.LastNode(); - chn.clear(); + if ( !quad._eIntNodes.empty() ) // connect pn2 with EDGE intersections { chn.push_back( pn2 ); @@ -4103,28 +4436,82 @@ namespace pn2 = chn.back(); } - int i; - for ( i = splits.size()-1; i >= 0; --i ) // connect new pn2 (at _eIntNodes) with a split + _Node* n = 0, *stopNode = avoidSplit.LastNode(); + + if ( pn2 == prevSplit.LastNode() && // pn2 is at avoidSplit.FirstNode() + !isCorner( stopNode )) // stopNode is in the middle of a _hexLinks + { + // move stopNode to a _hexNodes + for ( int iE = 0; iE < 4; ++iE ) // loop on 4 sides of a quadrangle + for ( size_t iL = 0; iL < quad._links[ iE ].NbResultLinks(); ++iL ) + { + const _Link* sideSplit = & quad._links[ iE ]._link->_splits[ iL ]; + if ( sideSplit == avoidSplit._link ) + { + if ( quad._links[ iE ].LastNode()->Node() ) + stopNode = quad._links[ iE ].LastNode(); + iE = 4; + break; + } + } + } + + // connect pn2 (probably new, at _eIntNodes) with a split + + int i, iConn; + size_t nbCommon; + TGeomID commonFaces[20]; + _Node* nPrev = nullptr; + for ( i = splits.size()-1; i >= 0; --i ) { if ( !splits[i] ) continue; - n = splits[i].LastNode(); - if ( n == stopNode ) - break; - if (( n != pn1 ) && - ( n->IsLinked( pn2->_intPoint, avoidFace )) && - ( !avoidFace || n->IsOnFace( avoidFace ))) - break; + bool stop = false; + for ( int is1st = 0; is1st < 2; ++is1st ) + { + _Node* nConn = is1st ? splits[i].FirstNode() : splits[i].LastNode(); + if ( nConn == nPrev ) + { + if ( n == nConn ) + iConn = i; + continue; + } + nPrev = nConn; + if (( stop = ( nConn == stopNode ))) + break; + // find a FACE connecting nConn with pn2 but not with an3 + if (( nConn != pn1 ) && + ( nConn->_intPoint && !nConn->_intPoint->_faceIDs.empty() ) && + ( nbCommon = nConn->GetCommonFaces( pn2->_intPoint, commonFaces ))) + { + bool a3Coonect = true; + for ( size_t iF = 0; iF < nbCommon && a3Coonect; ++iF ) + a3Coonect = an3->IsOnFace( commonFaces[ iF ]) || concaveFaces.count( commonFaces[ iF ]); + if ( a3Coonect ) + continue; - n = splits[i].FirstNode(); - if ( n == stopNode ) + if ( !n ) + { + n = nConn; + iConn = i + !is1st; + } + if ( nbCommon > 1 ) // nConn is linked with pn2 by an EDGE + { + n = nConn; + iConn = i + !is1st; + stop = true; + break; + } + } + } + if ( stop ) + { + i = iConn; break; - if (( n->IsLinked( pn2->_intPoint, avoidFace )) && - ( !avoidFace || n->IsOnFace( avoidFace ))) - break; - n = 0; + } } + if ( n && n != stopNode ) { if ( chn.empty() ) @@ -4136,8 +4523,8 @@ namespace else if ( !chn.empty() && chn.back()->_isInternalFlags ) { // INTERNAL FACE partially cuts the quad - for ( int i = chn.size() - 2; i >= 0; --i ) - chn.push_back( chn[ i ]); + for ( int ip = chn.size() - 2; ip >= 0; --ip ) + chn.push_back( chn[ ip ]); return true; } return false; @@ -4408,18 +4795,34 @@ namespace mesh->SetNodeOnEdge( nodes[iN], shapeID ); } else if ( toCheckNodePos && - !nodes[iN]->isMarked() && + !nodes[iN]->isMarked() && _grid->ShapeType( nodes[iN]->GetShapeID() ) == TopAbs_FACE ) { - _grid->SetOnShape( nodes[iN], noIntPnt, /*unset=*/true ); + _grid->SetOnShape( nodes[iN], noIntPnt, /*v=*/nullptr,/*unset=*/true ); nodes[iN]->setIsMarked( true ); } - } + } // loop to get nodes const SMDS_MeshElement* v = 0; if ( !volDef->_quantities.empty() ) { v = helper.AddPolyhedralVolume( nodes, volDef->_quantities ); + volDef->_size = SMDS_VolumeTool( v ).GetSize(); + if ( volDef->_size < 0 ) // invalid polyhedron + { + if ( ! SMESH_MeshEditor( helper.GetMesh() ).Reorient( v ) || // try to fix + SMDS_VolumeTool( v ).GetSize() < 0 ) + { + helper.GetMeshDS()->RemoveFreeElement( v, /*sm=*/nullptr, /*fromGroups=*/false ); + v = nullptr; + //_hasTooSmall = true; +#ifdef _DEBUG_ + std::cout << "Remove INVALID polyhedron, _cellID = " << _cellID + << " ijk = ( " << _i << " " << _j << " " << _k << " ) " + << " solid " << volDef->_solidID << std::endl; +#endif + } + } } else { @@ -4436,10 +4839,46 @@ namespace break; } } - if (( volDef->_volume = v )) + volDef->_volume = v; + nbAdded += bool( v ); + + } // loop on _volumeDefs chain + + // avoid creating overlapping volumes (bos #24052) + if ( nbAdded > 1 ) + { + double sumSize = 0, maxSize = 0; + _volumeDef* maxSizeDef = nullptr; + for ( _volumeDef* volDef = &_volumeDefs; volDef; volDef = volDef->_next ) { - helper.GetMeshDS()->SetMeshElementOnShape( v, volDef->_solidID ); - ++nbAdded; + if ( !volDef->_volume ) + continue; + sumSize += volDef->_size; + if ( volDef->_size > maxSize ) + { + maxSize = volDef->_size; + maxSizeDef = volDef; + } + } + if ( sumSize > _sideLength[0] * _sideLength[1] * _sideLength[2] * 1.05 ) + { + for ( _volumeDef* volDef = &_volumeDefs; volDef; volDef = volDef->_next ) + if ( volDef != maxSizeDef && volDef->_volume ) + { + helper.GetMeshDS()->RemoveFreeElement( volDef->_volume, /*sm=*/nullptr, + /*fromGroups=*/false ); + volDef->_volume = nullptr; + //volDef->_nodes.clear(); + --nbAdded; + } + } + } + + for ( _volumeDef* volDef = &_volumeDefs; volDef; volDef = volDef->_next ) + { + if ( volDef->_volume ) + { + helper.GetMeshDS()->SetMeshElementOnShape( volDef->_volume, volDef->_solidID ); } } @@ -4542,8 +4981,10 @@ namespace /*! * \brief Return true if a polyhedron passes _sizeThreshold criterion */ - bool Hexahedron::checkPolyhedronSize( bool cutByInternalFace ) const + bool Hexahedron::checkPolyhedronSize( bool cutByInternalFace, double & volume) const { + volume = 0; + if ( cutByInternalFace && !_grid->_toUseThresholdForInternalFaces ) { // check if any polygon fully lies on shared/internal FACEs @@ -4563,10 +5004,6 @@ namespace return true; } } - if ( this->hasStrangeEdge() ) - return true; - - double volume = 0; for ( size_t iP = 0; iP < _polygons.size(); ++iP ) { const _Face& polygon = _polygons[iP]; @@ -4584,6 +5021,9 @@ namespace } volume /= 6; + if ( this->hasStrangeEdge() && volume > 1e-13 ) + return true; + double initVolume = _sideLength[0] * _sideLength[1] * _sideLength[2]; return volume > initVolume / _grid->_sizeThreshold; @@ -4751,6 +5191,63 @@ namespace return false; } //================================================================================ + /*! + * \brief Return true if there are _eIntPoints at EDGEs forming a concave corner + */ + bool Hexahedron::hasEdgesAround( const ConcaveFace* cf ) const + { + int nbEdges = 0; + ConcaveFace foundGeomHolder; + for ( const E_IntersectPoint* ip : _eIntPoints ) + { + if ( cf->HasEdge( ip->_shapeID )) + { + if ( ++nbEdges == 2 ) + return true; + foundGeomHolder.SetEdge( ip->_shapeID ); + } + else if ( ip->_faceIDs.size() >= 3 ) + { + const TGeomID & vID = ip->_shapeID; + if ( cf->HasVertex( vID ) && !foundGeomHolder.HasVertex( vID )) + { + if ( ++nbEdges == 2 ) + return true; + foundGeomHolder.SetVertex( vID ); + } + } + } + + for ( const _Node& hexNode: _hexNodes ) + { + if ( !hexNode._node || !hexNode._intPoint ) + continue; + const B_IntersectPoint* ip = hexNode._intPoint; + if ( ip->_faceIDs.size() == 2 ) // EDGE + { + TGeomID edgeID = hexNode._node->GetShapeID(); + if ( cf->HasEdge( edgeID ) && !foundGeomHolder.HasEdge( edgeID )) + { + foundGeomHolder.SetEdge( edgeID ); + if ( ++nbEdges == 2 ) + return true; + } + } + else if ( ip->_faceIDs.size() >= 3 ) // VERTEX + { + TGeomID vID = hexNode._node->GetShapeID(); + if ( cf->HasVertex( vID ) && !foundGeomHolder.HasVertex( vID )) + { + if ( ++nbEdges == 2 ) + return true; + foundGeomHolder.SetVertex( vID ); + } + } + } + + return false; + } + //================================================================================ /*! * \brief Dump a link and return \c false */ @@ -4780,6 +5277,89 @@ namespace ( _grid->_coords[2][ _k+1 ] + _grid->_tol < uvw[2] )); } //================================================================================ + /*! + * \brief Find existing triangulation of a polygon + */ + int findExistingTriangulation( const SMDS_MeshElement* polygon, + //const SMDS_Mesh* mesh, + std::vector< const SMDS_MeshNode* >& nodes ) + { + int nbSplits = 0; + nodes.clear(); + std::vector twoNodes(2); + std::vector foundFaces; foundFaces.reserve(10); + std::set< const SMDS_MeshElement * > avoidFaces; avoidFaces.insert( polygon ); + + const int nbPolyNodes = polygon->NbCornerNodes(); + twoNodes[1] = polygon->GetNode( nbPolyNodes - 1 ); + for ( int iN = 0; iN < nbPolyNodes; ++iN ) // loop on border links of polygon + { + twoNodes[0] = polygon->GetNode( iN ); + + int nbFaces = SMDS_Mesh::GetElementsByNodes( twoNodes, foundFaces, SMDSAbs_Face ); + int nbOkFaces = 0; + for ( int iF = 0; iF < nbFaces; ++iF ) // keep faces lying over polygon + { + if ( avoidFaces.count( foundFaces[ iF ])) + continue; + int i, nbFaceNodes = foundFaces[ iF ]->NbCornerNodes(); + for ( i = 0; i < nbFaceNodes; ++i ) + { + const SMDS_MeshNode* n = foundFaces[ iF ]->GetNode( i ); + bool isCommonNode = ( n == twoNodes[0] || + n == twoNodes[1] || + polygon->GetNodeIndex( n ) >= 0 ); + if ( !isCommonNode ) + break; + } + if ( i == nbFaceNodes ) // all nodes of foundFaces[iF] are shared with polygon + if ( nbOkFaces++ != iF ) + foundFaces[ nbOkFaces-1 ] = foundFaces[ iF ]; + } + if ( nbOkFaces > 0 ) + { + int iFaceSelected = 0; + if ( nbOkFaces > 1 ) // select a face with minimal distance from polygon + { + double minDist = Precision::Infinite(); + for ( int iF = 0; iF < nbOkFaces; ++iF ) + { + int i, nbFaceNodes = foundFaces[ iF ]->NbCornerNodes(); + gp_XYZ gc = SMESH_NodeXYZ( foundFaces[ iF ]->GetNode( 0 )); + for ( i = 1; i < nbFaceNodes; ++i ) + gc += SMESH_NodeXYZ( foundFaces[ iF ]->GetNode( i )); + gc /= nbFaceNodes; + + double dist = SMESH_MeshAlgos::GetDistance( polygon, gc ); + if ( dist < minDist ) + { + minDist = dist; + iFaceSelected = iF; + } + } + } + if ( foundFaces[ iFaceSelected ]->NbCornerNodes() != 3 ) + return 0; + nodes.insert( nodes.end(), + foundFaces[ iFaceSelected ]->begin_nodes(), + foundFaces[ iFaceSelected ]->end_nodes()); + if ( !SMESH_MeshAlgos::IsRightOrder( foundFaces[ iFaceSelected ], + twoNodes[0], twoNodes[1] )) + { + // reverse just added nodes + std::reverse( nodes.end() - 3, nodes.end() ); + } + avoidFaces.insert( foundFaces[ iFaceSelected ]); + nbSplits++; + } + + twoNodes[1] = twoNodes[0]; + + } // loop on polygon nodes + + return nbSplits; + } + //================================================================================ /*! * \brief Divide a polygon into triangles and modify accordingly an adjacent polyhedron */ @@ -4793,7 +5373,12 @@ namespace const bool reinitVolume) { SMESH_MeshAlgos::Triangulate divider(/*optimize=*/false); - int nbTrias = divider.GetTriangles( polygon, face.myNodes ); + bool triangulationExist = false; + int nbTrias = findExistingTriangulation( polygon, face.myNodes ); + if ( nbTrias > 0 ) + triangulationExist = true; + else + nbTrias = divider.GetTriangles( polygon, face.myNodes ); face.myNodes.resize( nbTrias * 3 ); SMESH_MeshEditor::ElemFeatures newVolumeDef; @@ -4814,8 +5399,11 @@ namespace face.myNodes.begin(), face.myNodes.begin() + 3 ); meshDS->RemoveFreeElement( polygon, 0, false ); - newTriangle = meshDS->AddFace( face.myNodes[0], face.myNodes[1], face.myNodes[2] ); - meshDS->SetMeshElementOnShape( newTriangle, faceID ); + if ( !triangulationExist ) + { + newTriangle = meshDS->AddFace( face.myNodes[0], face.myNodes[1], face.myNodes[2] ); + meshDS->SetMeshElementOnShape( newTriangle, faceID ); + } } else { @@ -4832,8 +5420,11 @@ namespace newVolumeDef.myNodes.insert( newVolumeDef.myNodes.end(), face.myNodes.begin() + iN, face.myNodes.begin() + iN + 3 ); - newTriangle = meshDS->AddFace( face.myNodes[iN], face.myNodes[iN+1], face.myNodes[iN+2] ); - meshDS->SetMeshElementOnShape( newTriangle, faceID ); + if ( !triangulationExist ) + { + newTriangle = meshDS->AddFace( face.myNodes[iN], face.myNodes[iN+1], face.myNodes[iN+2] ); + meshDS->SetMeshElementOnShape( newTriangle, faceID ); + } } meshDS->RemoveFreeElement( volume.Element(), 0, false ); @@ -4848,6 +5439,36 @@ namespace return; } //================================================================================ + /*! + * \brief Look for a FACE supporting all given nodes made on EDGEs and VERTEXes + */ + TGeomID findCommonFace( const std::vector< const SMDS_MeshNode* > & nn, + const SMESH_Mesh* mesh ) + { + TGeomID faceID = 0; + TGeomID shapeIDs[20]; + for ( size_t iN = 0; iN < nn.size(); ++iN ) + shapeIDs[ iN ] = nn[ iN ]->GetShapeID(); + + SMESH_subMesh* sm = mesh->GetSubMeshContaining( shapeIDs[ 0 ]); + for ( const SMESH_subMesh * smFace : sm->GetAncestors() ) + { + if ( smFace->GetSubShape().ShapeType() != TopAbs_FACE ) + continue; + + faceID = smFace->GetId(); + + for ( size_t iN = 1; iN < nn.size() && faceID; ++iN ) + { + if ( !smFace->DependsOn( shapeIDs[ iN ])) + faceID = 0; + } + if ( faceID > 0 ) + break; + } + return faceID; + } + //================================================================================ /*! * \brief Create mesh faces at free facets */ @@ -4880,12 +5501,14 @@ namespace bndFacets.clear(); for ( int iF = 0, n = vTool.NbFaces(); iF < n; iF++ ) { - bool isBoundary = vTool.IsFreeFace( iF ); + const SMDS_MeshElement* otherVol; + bool isBoundary = vTool.IsFreeFace( iF, &otherVol ); if ( isBoundary ) { bndFacets.push_back( iF ); } - else if ( hasInternal ) + else if (( hasInternal ) || + ( !_grid->IsSolid( otherVol->GetShapeID() ))) { // check if all nodes are on internal/shared FACEs isBoundary = true; @@ -4929,18 +5552,8 @@ namespace if ( nn[ iN ]->GetPosition()->GetDim() == 2 ) faceID = nn[ iN ]->GetShapeID(); } - for ( size_t iN = 0; iN < nbFaceNodes && !faceID; ++iN ) - { - // look for a father FACE of EDGEs and VERTEXes - const TopoDS_Shape& s1 = _grid->Shape( nn[ iN ]->GetShapeID() ); - const TopoDS_Shape& s2 = _grid->Shape( nn[ iN+1 ]->GetShapeID() ); - if ( s1 != s2 && s1.ShapeType() == TopAbs_EDGE && s2.ShapeType() == TopAbs_EDGE ) - { - TopoDS_Shape f = helper.GetCommonAncestor( s1, s2, *helper.GetMesh(), TopAbs_FACE ); - if ( !f.IsNull() ) - faceID = _grid->ShapeID( f ); - } - } + if ( faceID == 0 ) + faceID = findCommonFace( face.myNodes, helper.GetMesh() ); bool toCheckFace = faceID && (( !isBoundary ) || ( hasInternal && _grid->_toUseThresholdForInternalFaces )); @@ -4953,12 +5566,15 @@ namespace if ( subID != faceID && !faceSM->DependsOn( subID )) faceID = 0; } - if ( !faceID && !isBoundary ) - continue; + // if ( !faceID && !isBoundary ) + // continue; } + if ( !faceID && !isBoundary ) + continue; } + // orient a new face according to supporting FACE orientation in shape_to_mesh - if ( !solid->IsOutsideOriented( faceID )) + if ( !isBoundary && !solid->IsOutsideOriented( faceID )) { if ( existFace ) editor.Reorient( existFace ); @@ -4987,14 +5603,15 @@ namespace } } - // split a polygon that will be used by other 3D algorithm if ( faceID && nbFaceNodes > 4 && !_grid->IsInternal( faceID ) && !_grid->IsShared( faceID ) && !_grid->IsBoundaryFace( faceID )) { - splitPolygon( newFace, vTool, iFacet, faceID, solidID, - face, editor, i+1 < bndFacets.size() ); + // split a polygon that will be used by other 3D algorithm + if ( !existFace ) + splitPolygon( newFace, vTool, iFacet, faceID, solidID, + face, editor, i+1 < bndFacets.size() ); } else { @@ -5061,6 +5678,8 @@ namespace for ( size_t i = 1; i < nodes.size(); i++ ) { + if ( mesh->FindEdge( nodes[i-1], nodes[i] )) + continue; SMDS_MeshElement* segment = mesh->AddEdge( nodes[i-1], nodes[i] ); mesh->SetMeshElementOnShape( segment, e2ff->first ); } @@ -5138,7 +5757,9 @@ namespace // return created volumes for ( _volumeDef* volDef = &_volumeDefs; volDef; volDef = volDef->_next ) { - if ( volDef->_volume && !volDef->_volume->isMarked() ) + if ( volDef ->_volume && + !volDef->_volume->IsNull() && + !volDef->_volume->isMarked() ) { volDef->_volume->setIsMarked( true ); boundaryElems.push_back( volDef->_volume ); @@ -5874,7 +6495,10 @@ bool StdMeshers_Cartesian_3D::Compute(SMESH_Mesh & theMesh, { multiset< F_IntersectPoint >::iterator ip = lines[i]._intPoints.begin(); for ( ; ip != lines[i]._intPoints.end(); ++ip ) - if ( ip->_node && ip->_node->NbInverseElements() == 0 && !ip->_node->isMarked() ) + if ( ip->_node && + !ip->_node->IsNull() && + ip->_node->NbInverseElements() == 0 && + !ip->_node->isMarked() ) { nodesToRemove.push_back( ip->_node ); ip->_node->setIsMarked( true ); @@ -5883,7 +6507,9 @@ bool StdMeshers_Cartesian_3D::Compute(SMESH_Mesh & theMesh, } // get grid nodes for ( size_t i = 0; i < grid._nodes.size(); ++i ) - if ( grid._nodes[i] && grid._nodes[i]->NbInverseElements() == 0 && + if ( grid._nodes[i] && + !grid._nodes[i]->IsNull() && + grid._nodes[i]->NbInverseElements() == 0 && !grid._nodes[i]->isMarked() ) { nodesToRemove.push_back( grid._nodes[i] ); diff --git a/src/StdMeshers/StdMeshers_Prism_3D.cxx b/src/StdMeshers/StdMeshers_Prism_3D.cxx index 962ae75bd..2a8baf1ec 100644 --- a/src/StdMeshers/StdMeshers_Prism_3D.cxx +++ b/src/StdMeshers/StdMeshers_Prism_3D.cxx @@ -99,7 +99,7 @@ namespace { TmpMesh() { _isShapeToMesh = (_id = 0); - _myMeshDS = new SMESHDS_Mesh( _id, true ); + _meshDS = new SMESHDS_Mesh( _id, true ); } }; //======================================================================= diff --git a/src/StdMeshers/StdMeshers_QuadFromMedialAxis_1D2D.cxx b/src/StdMeshers/StdMeshers_QuadFromMedialAxis_1D2D.cxx index 7efd9af5f..3f6730bf9 100644 --- a/src/StdMeshers/StdMeshers_QuadFromMedialAxis_1D2D.cxx +++ b/src/StdMeshers/StdMeshers_QuadFromMedialAxis_1D2D.cxx @@ -240,7 +240,7 @@ namespace { TmpMesh() { - _myMeshDS = new SMESHDS_Mesh(/*id=*/0, /*isEmbeddedMode=*/true); + _meshDS = new SMESHDS_Mesh(/*id=*/0, /*isEmbeddedMode=*/true); } }; diff --git a/src/StdMeshers/StdMeshers_Quadrangle_2D.hxx b/src/StdMeshers/StdMeshers_Quadrangle_2D.hxx index b14f7a11d..eb43083cb 100644 --- a/src/StdMeshers/StdMeshers_Quadrangle_2D.hxx +++ b/src/StdMeshers/StdMeshers_Quadrangle_2D.hxx @@ -46,11 +46,11 @@ struct uvPtStruct; enum TSideID { QUAD_BOTTOM_SIDE=0, QUAD_RIGHT_SIDE, QUAD_TOP_SIDE, QUAD_LEFT_SIDE, NB_QUAD_SIDES }; typedef uvPtStruct UVPtStruct; -struct FaceQuadStruct +struct STDMESHERS_EXPORT FaceQuadStruct { - struct Side // a side of FaceQuadStruct + struct STDMESHERS_EXPORT Side // a side of FaceQuadStruct { - struct Contact // contact of two sides + struct STDMESHERS_EXPORT Contact // contact of two sides { int point; // index of a grid point of this side where two sides meat Side* other_side; diff --git a/src/StdMeshers/StdMeshers_ViscousLayers.cxx b/src/StdMeshers/StdMeshers_ViscousLayers.cxx index 154908469..4ed66607a 100644 --- a/src/StdMeshers/StdMeshers_ViscousLayers.cxx +++ b/src/StdMeshers/StdMeshers_ViscousLayers.cxx @@ -49,13 +49,13 @@ #include "SMESH_subMeshEventListener.hxx" #include "StdMeshers_FaceSide.hxx" #include "StdMeshers_ProjectionUtils.hxx" +#include "StdMeshers_Quadrangle_2D.hxx" #include "StdMeshers_ViscousLayers2D.hxx" #include #include #include #include -//#include #include #include #include @@ -101,7 +101,7 @@ #include #ifdef _DEBUG_ -//#define __myDEBUG +#define __myDEBUG //#define __NOT_INVALIDATE_BAD_SMOOTH //#define __NODES_AT_POS #endif @@ -385,6 +385,7 @@ namespace VISCOUS_3D struct _LayerEdge; struct _EdgesOnShape; struct _Smoother1D; + struct _Mapper2D; typedef map< const SMDS_MeshNode*, _LayerEdge*, TIDCompare > TNode2Edge; //-------------------------------------------------------------------------------- @@ -444,6 +445,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 +499,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 +628,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::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 +691,8 @@ namespace VISCOUS_3D Handle(ShapeAnalysis_Surface) _offsetSurf; _LayerEdge* _edgeForOffset; + double _offsetValue; + _Mapper2D* _mapper2D; _SolidData* _data; // parent SOLID @@ -685,8 +706,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 +949,7 @@ namespace VISCOUS_3D const StdMeshers_ViscousLayers* hyp, const TopoDS_Shape& hypShape, set& 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 +1129,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 +1478,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 +1530,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 +1572,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 +1604,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::min() )) edgeDir[i] /= sqrt( size2 ); @@ -1559,15 +1624,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 +1826,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 +2028,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 +2035,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 +2052,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 +2680,7 @@ bool _ViscousBuilder::makeLayer(_SolidData& data) // Create temporary faces and _LayerEdge's + debugMsg( "######################" ); dumpFunction(SMESH_Comment("makeLayers_")<& edgesByGeom = data._edgesOnShape; @@ -2677,7 +2741,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 @@ -2717,7 +2781,7 @@ bool _ViscousBuilder::makeLayer(_SolidData& data) } dumpMove(edge->_nodes.back()); - if ( edge->_cosin > faceMaxCosin ) + if ( edge->_cosin > faceMaxCosin && !edge->Is( _LayerEdge::BLOCKED )) { faceMaxCosin = edge->_cosin; maxCosinEdge = edge; @@ -2767,6 +2831,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 +3220,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 +3404,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 +3450,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 +3462,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 +3474,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 +3514,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 +3635,7 @@ bool _EdgesOnShape::GetNormal( const SMDS_MeshElement* face, gp_Vec& norm ) _EdgesOnShape::~_EdgesOnShape() { delete _edgeSmoother; + delete _mapper2D; } //================================================================================ @@ -3601,13 +3717,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 +3813,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 +3868,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 ) { @@ -3786,7 +3923,8 @@ bool _ViscousBuilder::setEdgeData(_LayerEdge& edge, 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 +4291,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 +4542,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; } //================================================================================ @@ -4962,24 +5111,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")<_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")<_mapper2D ) + continue; vector< _LayerEdge* > & edges = eosC1[ iEOS ]->_edges; for ( size_t i = 0; i < edges.size(); ++i ) { @@ -5061,11 +5232,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 +5408,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 ) @@ -5508,14 +5679,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 +5738,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 +5750,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 +5795,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 +5837,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 +5859,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 +5868,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 ); + } + } } //================================================================================ @@ -6330,7 +6564,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 +6702,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 +6939,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 +7642,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 +9929,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 +9974,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 +9989,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 +10456,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 +10497,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 +10513,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::min() ) - h0 = T / N; - else - h0 = T * ( f - 1 )/( fPowN - 1 ); - - const double zeroLen = std::numeric_limits::min(); // create intermediate nodes - double hSum = 0, hi = h0/f; + const double h0 = eos._hyp.Get1stLayerThickness( segLen.back() ); + const double zeroLen = std::numeric_limits::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; @@ -10561,14 +10893,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 +10962,15 @@ namespace VISCOUS_3D if ( !periodic._trsf.Solve( srcPnts, tgtPnts )) { continue; } - double tol = std::numeric_limits::max(); + double tol = std::numeric_limits::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 +10978,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; @@ -11422,6 +11757,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 +11906,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 +12142,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 +12169,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::min() ) continue; @@ -11864,6 +12202,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 +12439,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 +12519,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 +12542,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 +12617,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 diff --git a/src/StdMeshersGUI/CMakeLists.txt b/src/StdMeshersGUI/CMakeLists.txt index 1b28ee703..15150fd2e 100644 --- a/src/StdMeshersGUI/CMakeLists.txt +++ b/src/StdMeshersGUI/CMakeLists.txt @@ -32,6 +32,7 @@ INCLUDE_DIRECTORIES( ${Boost_INCLUDE_DIRS} ${QWT_INCLUDE_DIR} ${OMNIORB_INCLUDE_DIR} + ${MEDCOUPLING_INCLUDE_DIRS} ${PROJECT_SOURCE_DIR}/src/SMESH ${PROJECT_SOURCE_DIR}/src/SMESHUtils ${PROJECT_SOURCE_DIR}/src/SMESH_I diff --git a/src/StdMeshersGUI/StdMeshersGUI_DistrPreview.cxx b/src/StdMeshersGUI/StdMeshersGUI_DistrPreview.cxx index b3523818b..b2a4be767 100644 --- a/src/StdMeshersGUI/StdMeshersGUI_DistrPreview.cxx +++ b/src/StdMeshersGUI/StdMeshersGUI_DistrPreview.cxx @@ -320,13 +320,8 @@ void StdMeshersGUI_DistrPreview::update() setAxisScale( myDensity->xAxis(), min_x, max_x ); setAxisScale( myDensity->yAxis(), -#ifdef WIN32 - min( 0.0, min_y ), - max( 0.0, max_y ) -#else std::min( 0.0, min_y ), std::max( 0.0, max_y ) -#endif ); myDensity->setSamples( x, y, size ); if( x ) diff --git a/src/StdMeshersGUI/StdMeshersGUI_ObjectReferenceParamWdg.h b/src/StdMeshersGUI/StdMeshersGUI_ObjectReferenceParamWdg.h index 46ac6942c..2e5d3792c 100644 --- a/src/StdMeshersGUI/StdMeshersGUI_ObjectReferenceParamWdg.h +++ b/src/StdMeshersGUI/StdMeshersGUI_ObjectReferenceParamWdg.h @@ -53,8 +53,8 @@ class STDMESHERSGUI_EXPORT StdMeshersGUI_ObjectReferenceParamWdg : public QWidge { Q_OBJECT -public: - StdMeshersGUI_ObjectReferenceParamWdg( SUIT_SelectionFilter* filter, + public: + StdMeshersGUI_ObjectReferenceParamWdg( SUIT_SelectionFilter* filter, QWidget* parent, bool multiSelection=false /* ,bool stretch=true*/); @@ -67,7 +67,7 @@ public: void SetObjects(SMESH::string_array_var& objEntries); - template + template typename TInterface::_var_type GetObject(size_t i=0) const { if ( IsObjectSelected(i) ) return TInterface::_narrow(myObjects[i]); return TInterface::_nil(); @@ -75,6 +75,7 @@ public: size_t NbObjects() const { return myObjects.size(); } + // Return object entries QString GetValue() const { return myParamValue; } bool IsObjectSelected(size_t i=0) const @@ -82,60 +83,60 @@ public: /*! * \brief Get the selection status - * - * Useful to know which Object Reference param widget is activated - * to be able to activate the next one when the content of this - * one has been modified + * + * Useful to know which Object Reference param widget is activated + * to be able to activate the next one when the content of this + * one has been modified */ bool IsSelectionActivated() const { return mySelectionActivated; } void AvoidSimultaneousSelection( StdMeshersGUI_ObjectReferenceParamWdg* other); - + void SetDefaultText(QString defaultText="", QString styleSheet=""); -public slots: + public slots: /*! * \brief Activates selection (if not yet done), emits selectionActivated() - * - * Useful to deactivate one Object Reference param widget when an other - * one is activated + * + * Useful to deactivate one Object Reference param widget when an other + * one is activated */ void activateSelection(); void deactivateSelection(); -signals: + signals: /*! * \brief Emitted when selection is activated - * - * Useful to deactivate one Object Reference param widget when an other - * one is activated + * + * Useful to deactivate one Object Reference param widget when an other + * one is activated */ void selectionActivated(); void contentModified(); - -private slots: - void onSelectionDone(); -private: + private slots: + void onSelectionDone(); + + private: void init(); - -private: + + private: bool myMultiSelection; std::vector myObjects; - SUIT_SelectionFilter* myFilter; - bool mySelectionActivated; - bool myStretchActivated; + SUIT_SelectionFilter* myFilter; + bool mySelectionActivated; + bool myStretchActivated; - SMESHGUI* mySMESHGUI; - LightApp_SelectionMgr* mySelectionMgr; + SMESHGUI* mySMESHGUI; + LightApp_SelectionMgr* mySelectionMgr; - QLineEdit* myObjNameLineEdit; - QPushButton* mySelButton; - QString myParamValue; - QString myEmptyText; - QString myEmptyStyleSheet; + QLineEdit* myObjNameLineEdit; + QPushButton* mySelButton; + QString myParamValue; + QString myEmptyText; + QString myEmptyStyleSheet; }; #endif // STDMESHERSGUI_OBJECTREFERENCEPARAMWDG_H diff --git a/src/StdMeshers_I/CMakeLists.txt b/src/StdMeshers_I/CMakeLists.txt index 27734abf9..c6262c72d 100644 --- a/src/StdMeshers_I/CMakeLists.txt +++ b/src/StdMeshers_I/CMakeLists.txt @@ -27,6 +27,7 @@ INCLUDE_DIRECTORIES( ${MEDFILE_INCLUDE_DIRS} ${Boost_INCLUDE_DIRS} ${OMNIORB_INCLUDE_DIR} + ${MEDCOUPLING_INCLUDE_DIRS} ${PROJECT_SOURCE_DIR}/src/SMESHImpl ${PROJECT_SOURCE_DIR}/src/SMESH ${PROJECT_SOURCE_DIR}/src/SMESHUtils diff --git a/src/StdMeshers_I/StdMeshers_ObjRefUlils.hxx b/src/StdMeshers_I/StdMeshers_ObjRefUlils.hxx index 24cfdf16f..d03ff314b 100644 --- a/src/StdMeshers_I/StdMeshers_ObjRefUlils.hxx +++ b/src/StdMeshers_I/StdMeshers_ObjRefUlils.hxx @@ -29,6 +29,7 @@ #define StdMeshers_ObjRefUlils_HeaderFile #include "SMESH_Gen_i.hxx" +#include "SMESH_StdMeshers_I.hxx" /*! * \brief Class encapsulates methods @@ -70,7 +71,7 @@ public: * \param theEntry - study entry * \retval TopoDS_Shape - result TopoDS_Shape */ - static TopoDS_Shape EntryToShape(const std::string theEntry); + STDMESHERS_I_EXPORT static TopoDS_Shape EntryToShape(const std::string theEntry); /*! * \brief Return study entry of GEOM Object diff --git a/src/Tools/blocFissure/gmu/getStatsMaillageFissure.py b/src/Tools/blocFissure/gmu/getStatsMaillageFissure.py index 0633c3040..2f1a6813d 100644 --- a/src/Tools/blocFissure/gmu/getStatsMaillageFissure.py +++ b/src/Tools/blocFissure/gmu/getStatsMaillageFissure.py @@ -50,8 +50,8 @@ def getStatsMaillageFissure(maillage, referencesMaillageFissure, maillageFissure ok_maillage = True with open(fichierStatMaillageFissure, "w") as fic_stat : - # Le nombre d'arêtes, de quadrangles ou d'hexaèdres doit être rigoureusement identique - for key in ('Entity_Quad_Edge', 'Entity_Quad_Quadrangle', 'Entity_Quad_Hexa'): + # Le nombre de quadrangles ou d'hexaèdres doit être rigoureusement identique + for key in ('Entity_Quad_Quadrangle', 'Entity_Quad_Hexa'): if d_resu[key] != referencesMaillageFissure[key]: text = "Ecart" ok_maillage = False @@ -62,9 +62,9 @@ def getStatsMaillageFissure(maillage, referencesMaillageFissure, maillageFissure fic_stat.write(text+"\n") text_2 += " {} = {}, \\\n".format(key,d_resu[key]) - # Le nombre de noeuds, de triangles, de tétraèdres ou de pyramides peut varier du fait des algorithmes. On tolère 5% d'écart. + # Le nombre de noeuds, d'arêtes, de triangles, de tétraèdres ou de pyramides peut varier du fait des algorithmes. On tolère 5% d'écart. tolerance = 0.05 - for key in ('Entity_Node', 'Entity_Quad_Triangle', 'Entity_Quad_Tetra', 'Entity_Quad_Pyramid', 'Entity_Quad_Penta'): + for key in ('Entity_Node', 'Entity_Quad_Edge', 'Entity_Quad_Triangle', 'Entity_Quad_Tetra', 'Entity_Quad_Pyramid', 'Entity_Quad_Penta'): if d_resu[key] == referencesMaillageFissure[key]: text = "Valeur_OK" elif (d_resu[key] < (1.0 - tolerance)*referencesMaillageFissure[key]) \ diff --git a/src/Tools/padder/meshjob/impl/CMakeLists.txt b/src/Tools/padder/meshjob/impl/CMakeLists.txt index cd76a642f..dedd03cb5 100644 --- a/src/Tools/padder/meshjob/impl/CMakeLists.txt +++ b/src/Tools/padder/meshjob/impl/CMakeLists.txt @@ -26,6 +26,7 @@ INCLUDE_DIRECTORIES( ${Boost_INCLUDE_DIRS} ${OMNIORB_INCLUDE_DIR} ${LIBXML2_INCLUDE_DIR} + ${MEDCOUPLING_INCLUDE_DIRS} ${PROJECT_SOURCE_DIR}/src/SMESH ${PROJECT_SOURCE_DIR}/src/SMESH_I ${PROJECT_SOURCE_DIR}/src/SMESHDS