diff --git a/CMakeLists.txt b/CMakeLists.txt index 68f91de51..ddcef2ba0 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -17,22 +17,15 @@ # See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com # CMAKE_MINIMUM_REQUIRED(VERSION 2.8.8 FATAL_ERROR) -PROJECT(SalomeSMESH C CXX) - INCLUDE(CMakeDependentOption) -# Versioning -# =========== -# Project name, upper case +# Project name +# ============ +# original +PROJECT(SalomeSMESH C CXX) +# upper case STRING(TOUPPER ${PROJECT_NAME} PROJECT_NAME_UC) -SET(${PROJECT_NAME_UC}_MAJOR_VERSION 9) -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}) -SET(${PROJECT_NAME_UC}_VERSION_DEV 1) - # Common CMake macros # =================== SET(CONFIGURATION_ROOT_DIR $ENV{CONFIGURATION_ROOT_DIR} CACHE PATH "Path to the Salome CMake configuration files") @@ -43,6 +36,11 @@ ELSE() MESSAGE(FATAL_ERROR "We absolutely need the Salome CMake configuration files, please define CONFIGURATION_ROOT_DIR !") ENDIF() +# Versioning +# =========== +SALOME_SETUP_VERSION(9.8.0 DEVELOPMENT) +MESSAGE(STATUS "Building ${PROJECT_NAME_UC} ${${PROJECT_NAME_UC}_VERSION} from \"${${PROJECT_NAME_UC}_GIT_SHA1}\"") + # Find KERNEL # =========== SET(KERNEL_ROOT_DIR $ENV{KERNEL_ROOT_DIR} CACHE PATH "Path to the Salome KERNEL") @@ -328,7 +326,6 @@ ENDIF() # Header configuration # ==================== -SALOME_XVERSION(${PROJECT_NAME}) SALOME_CONFIGURE_FILE(SMESH_version.h.in SMESH_version.h INSTALL ${SALOME_INSTALL_HEADERS}) # Configuration export diff --git a/bin/VERSION.in b/bin/VERSION.in index 587f19c1f..73c769017 100644 --- a/bin/VERSION.in +++ b/bin/VERSION.in @@ -1,3 +1,4 @@ [SALOME SMESH] : @SALOMESMESH_VERSION@ [DEVELOPMENT] : @SALOMESMESH_VERSION_DEV@ [DESCRIPTION] : SALOME Mesh module +[SHA1] : @SALOMESMESH_GIT_SHA1@ diff --git a/doc/salome/examples/CMakeLists.txt b/doc/salome/examples/CMakeLists.txt index 7ecb2db4a..df54d5a08 100644 --- a/doc/salome/examples/CMakeLists.txt +++ b/doc/salome/examples/CMakeLists.txt @@ -42,6 +42,7 @@ SALOME_INSTALL_SCRIPTS("${EXAMPLES_TESTS}" ${SALOME_INSTALL_DOC}/examples/SMESH) SET(TEST_INSTALL_DIRECTORY ${SALOME_INSTALL_SCRIPT_SCRIPTS}/test) INSTALL(FILES ${GOOD_TESTS} ${BAD_TESTS} ${SESSION_FREE_TESTS} DESTINATION ${TEST_INSTALL_DIRECTORY}) +INSTALL(FILES Mesh_tri.med DESTINATION ${TEST_INSTALL_DIRECTORY}) INSTALL(FILES CTestTestfileInstall.cmake DESTINATION ${TEST_INSTALL_DIRECTORY} diff --git a/doc/salome/examples/MGAdaptTests_without_session.py b/doc/salome/examples/MGAdaptTests_without_session.py index aa3f087a2..2f0621d70 100644 --- a/doc/salome/examples/MGAdaptTests_without_session.py +++ b/doc/salome/examples/MGAdaptTests_without_session.py @@ -450,7 +450,7 @@ if __name__ == "__main__" : L_OPTIONS.append("05") L_OPTIONS.append("06") L_OPTIONS.append("08") - #L_OPTIONS.append("13") + L_OPTIONS.append("13") # 2. Lancement de la classe diff --git a/doc/salome/examples/Mesh_tri.med b/doc/salome/examples/Mesh_tri.med new file mode 100644 index 000000000..e5a198400 Binary files /dev/null and b/doc/salome/examples/Mesh_tri.med differ diff --git a/doc/salome/examples/doublenodes_polyhedra.py b/doc/salome/examples/doublenodes_polyhedra.py new file mode 100644 index 000000000..7a28ea7b2 --- /dev/null +++ b/doc/salome/examples/doublenodes_polyhedra.py @@ -0,0 +1,231 @@ +#!/usr/bin/env python + +import sys +import salome + +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 Sketch +Sketch_1 = model.addSketch(Part_1_doc, model.defaultPlane("XOZ")) + +### Create SketchLine +SketchLine_1 = Sketch_1.addLine(100, 0, 0, 0) + +### Create SketchProjection +SketchProjection_1 = Sketch_1.addProjection(model.selection("VERTEX", "PartSet/Origin"), False) +SketchPoint_1 = SketchProjection_1.createdFeature() +Sketch_1.setCoincident(SketchLine_1.endPoint(), SketchPoint_1.result()) + +### Create SketchLine +SketchLine_2 = Sketch_1.addLine(0, 0, 0, 100) + +### Create SketchLine +SketchLine_3 = Sketch_1.addLine(0, 100, 100, 100) + +### Create SketchLine +SketchLine_4 = Sketch_1.addLine(100, 100, 100, 0) +Sketch_1.setCoincident(SketchLine_4.endPoint(), SketchLine_1.startPoint()) +Sketch_1.setCoincident(SketchLine_1.endPoint(), SketchLine_2.startPoint()) +Sketch_1.setCoincident(SketchLine_2.endPoint(), SketchLine_3.startPoint()) +Sketch_1.setCoincident(SketchLine_3.endPoint(), SketchLine_4.startPoint()) +Sketch_1.setHorizontal(SketchLine_1.result()) +Sketch_1.setVertical(SketchLine_2.result()) +Sketch_1.setHorizontal(SketchLine_3.result()) +Sketch_1.setVertical(SketchLine_4.result()) +Sketch_1.setEqual(SketchLine_3.result(), SketchLine_4.result()) +Sketch_1.setLength(SketchLine_1.result(), 100) + +### Create SketchLine +SketchLine_5 = Sketch_1.addLine(0, 50, 100, 50) +Sketch_1.setCoincident(SketchLine_5.startPoint(), SketchLine_2.result()) +Sketch_1.setCoincident(SketchLine_5.endPoint(), SketchLine_4.result()) +Sketch_1.setHorizontal(SketchLine_5.result()) + +### Create SketchLine +SketchLine_6 = Sketch_1.addLine(50, 50.00000000000001, 50, 0) +Sketch_1.setCoincident(SketchLine_6.endPoint(), SketchLine_1.result()) +Sketch_1.setVertical(SketchLine_6.result()) +Sketch_1.setCoincident(SketchLine_6.startPoint(), SketchLine_5.result()) +Sketch_1.setMiddlePoint(SketchLine_6.startPoint(), SketchLine_5.result()) +Sketch_1.setMiddlePoint(SketchLine_5.startPoint(), SketchLine_2.result()) +model.do() + +### Create Extrusion +Extrusion_1 = model.addExtrusion(Part_1_doc, [model.selection("COMPOUND", "Sketch_1")], model.selection(), 100, 0, "Faces|Wires") + +### Create Group +Group_1 = model.addGroup(Part_1_doc, "Faces", [model.selection("FACE", "Extrusion_1_1_1/Generated_Face&Sketch_1/SketchLine_5"), model.selection("FACE", "(Extrusion_1_1_3/Generated_Face&Sketch_1/SketchLine_4)(Extrusion_1_1_3/From_Face)(Extrusion_1_1_3/To_Face)(Extrusion_1_1_3/Generated_Face&Sketch_1/SketchLine_3)2(Extrusion_1_1_3/Generated_Face&Sketch_1/SketchLine_2)2")]) +Group_1.setName("crack_1") +Group_1.result().setName("crack_1") + +### Create Group +Group_2 = model.addGroup(Part_1_doc, "Faces", [model.selection("FACE", "Extrusion_1_1_1/Generated_Face&Sketch_1/SketchLine_6")]) +Group_2.setName("crack_2") +Group_2.result().setName("crack_2") + +### Create Group +Group_3 = model.addGroup(Part_1_doc, "Faces", [model.selection("COMPSOLID", "Extrusion_1_1")]) +Group_3.setName("all_faces") +Group_3.result().setName("all_faces") + +### Create GroupSubstraction +GroupSubstraction_1 = model.addGroupSubstraction(Part_1_doc, [model.selection("COMPOUND", "all_faces")], [model.selection("COMPOUND", "crack_1"), model.selection("COMPOUND", "crack_2")]) +GroupSubstraction_1.result().setName("sides") + +### Create Group +Group_4 = model.addGroup(Part_1_doc, "Edges", [model.selection("EDGE", "[Extrusion_1_1_3/Generated_Face&Sketch_1/SketchLine_3][Extrusion_1_1_3/To_Face]")]) +Group_4.setName("top_edge") +Group_4.result().setName("top_edge") + +### Create Group +Group_5 = model.addGroup(Part_1_doc, "Solids", [model.selection("SOLID", "Extrusion_1_1_3")]) +Group_5.setName("Solid_1") +Group_5.result().setName("Solid_1") + +### Create Group +Group_6 = model.addGroup(Part_1_doc, "Solids", [model.selection("SOLID", "Extrusion_1_1_1")]) +Group_6.setName("Solid_2") +Group_6.result().setName("Solid_2") + +### Create Group +Group_7 = model.addGroup(Part_1_doc, "Solids", [model.selection("SOLID", "Extrusion_1_1_2")]) +Group_7.setName("Solid_3") +Group_7.result().setName("Solid_3") + +model.end() + +### +### SHAPERSTUDY component +### + +model.publishToShaperStudy() +import SHAPERSTUDY +shapes = SHAPERSTUDY.shape(model.featureStringId(Extrusion_1)) + +Extrusion_1_1 = shapes[0] +groups = shapes[1:] + +# dict of groups by their name +d_groups = {} +for gr in groups: + name = gr.GetName() + d_groups[name] = gr + +### +### SMESH component +### + +import SMESH, SALOMEDS +from salome.smesh import smeshBuilder + +smesh = smeshBuilder.New() + +# Create an hexahedral mesh or polyhedral mesh +# @param algo: "hexahedra", "polyhedra" or "polygons" +def createMesh(algo): + + nb_segs = 5 + Mesh_1 = smesh.Mesh(Extrusion_1_1) + mesh_name = "Mesh_%s"%algo + Mesh_1.SetName(mesh_name) + + algo_1d = Mesh_1.Segment() + algo_1d.NumberOfSegments(nb_segs) + + if algo == "hexahedra": + Mesh_1.Quadrangle(algo=smeshBuilder.QUADRANGLE) + Mesh_1.Hexahedron(algo=smeshBuilder.Hexa) + elif algo == "polyhedra": + Mesh_1.Quadrangle(algo=smeshBuilder.QUADRANGLE) + Mesh_1.Polyhedron() + elif algo == "polygons": + Mesh_1.Polygon() + Mesh_1.Polyhedron() + else: + raise Exception("not expected algo: ", algo) + + d_mesh_groups = {} + # Create group of faces + for name, gr in d_groups.items(): + if name.startswith("crack") or name.startswith("Solid_"): + gr_mesh = Mesh_1.Group(gr) + d_mesh_groups[name] = gr_mesh + + # Group on nodes + gr_sides_1 = Mesh_1.GroupOnGeom(d_groups["sides"],'sides',SMESH.NODE) + + # sub-mesh on top edge + algo_1d_sub = Mesh_1.Segment(geom=d_groups["top_edge"]) + algo_1d_sub.NumberOfSegments(2*nb_segs) + algo_1d_sub.Propagation() + + isDone = Mesh_1.Compute() + + nb_nodes = Mesh_1.NbNodes() + # Create 2 cracks by two calls of DoubleNodeElemGroups + + # FIRST CRACK + # get affected elements on crack_1 + [ affectedVolumes_1, affectedFaces_1, affectedEdges_1 ] = Mesh_1.AffectedElemGroupsInRegion( [ d_mesh_groups["crack_1" ] ], [ gr_sides_1 ], None ) + # affectedVolumes_1 is d_mesh_groups["Solid_1"] => use one or the other + # double nodes on crack_1 + [ crack_1_double_faces, crack_1_double_nodes ] = Mesh_1.DoubleNodeElemGroups( [ d_mesh_groups["crack_1" ] ], [ gr_sides_1 ], [ affectedVolumes_1, affectedFaces_1, affectedEdges_1 ], 1, 1 ) + + # check new nodes were added + new_nb_nodes_1 = Mesh_1.NbNodes() + assert new_nb_nodes_1 > nb_nodes + + # check number of new nodes + if algo != "polygons": + assert new_nb_nodes_1-nb_nodes == (nb_segs*2-1)*(nb_segs-1) + else: + assert new_nb_nodes_1-nb_nodes == nb_segs-1 + + # check new nodes where affected to volume elements + affectedVolumes_1_nodes = affectedVolumes_1.GetNodeIDs() + for n in range(nb_nodes +1, new_nb_nodes_1): + assert n in affectedVolumes_1_nodes, "New node not affected to affectedVolumes_1 in %s"%mesh_name + + # SECOND CRACK + # get affected elements on crack_2 + [ affectedVolumes_2, affectedFaces_2, affectedEdges_2 ] = Mesh_1.AffectedElemGroupsInRegion( [ d_mesh_groups["crack_2" ] ], [ gr_sides_1 ], None ) + # double nodes on crack_2 + # affectedVolumes_2 is d_mesh_groups["Solid_3"] => use one or the other + [ crack_2_double_faces, crack_2_double_nodes ] = Mesh_1.DoubleNodeElemGroups( [ d_mesh_groups["crack_2" ] ], [ gr_sides_1 ], [ affectedVolumes_2, affectedFaces_2, affectedEdges_2 ], 1, 1 ) + + # check new nodes were added + new_nb_nodes_2 = Mesh_1.NbNodes() + assert new_nb_nodes_2 > new_nb_nodes_1 + + # check number of new nodes + if algo != "polygons": + assert new_nb_nodes_2-new_nb_nodes_1 == (nb_segs-1)*nb_segs + else: + assert new_nb_nodes_2-new_nb_nodes_1 == nb_segs-1 + + # check new nodes where affected to volume elements + affectedVolumes_2_nodes = affectedVolumes_2.GetNodeIDs() + for n in range(new_nb_nodes_1 +1, new_nb_nodes_2): + assert n in affectedVolumes_2_nodes, "New node not affected to affectedVolumes_2 in %s"%mesh_name + +createMesh("hexahedra") +createMesh("polyhedra") +createMesh("polygons") + + +if salome.sg.hasDesktop(): + salome.sg.updateObjBrowser() diff --git a/doc/salome/examples/ssl_hdf5_symbols_conflicts.py b/doc/salome/examples/ssl_hdf5_symbols_conflicts.py new file mode 100644 index 000000000..c88863890 --- /dev/null +++ b/doc/salome/examples/ssl_hdf5_symbols_conflicts.py @@ -0,0 +1,21 @@ +#!/usr/bin/env python + +""" +tuleap26358 : Non regression test pointing to an incompatibiliy between hdf5 symbols in CGNS and hdf5 symbols +in hdf5 library. +""" + +import salome +salome.standalone() +salome.salome_init() +import SMESH, SALOMEDS +from salome.smesh import smeshBuilder + +smesh = smeshBuilder.New() + +inputMED="Mesh_tri.med" + +([Mesh_tri_1], status) = smesh.CreateMeshesFromMED(inputMED) +import SMESH +if status != SMESH.DRS_OK: + raise RuntimeError("Test failed") diff --git a/doc/salome/examples/test_smeshplugins.py b/doc/salome/examples/test_smeshplugins.py index 48f12085c..a6efe765c 100644 --- a/doc/salome/examples/test_smeshplugins.py +++ b/doc/salome/examples/test_smeshplugins.py @@ -17,6 +17,7 @@ __revision__ = "V1.0" ComputeMeshes = True import salome +import platform salome.salome_init_without_session() theStudy = salome.myStudy @@ -74,23 +75,27 @@ while not ERROR : print(TEXTE+": OK") # B.2. Gmsh - TEXTE = "Gmsh" - MESH_2 = smesh.Mesh(BOX) - smesh.SetName(MESH_2.GetMesh(), "M_"+TEXTE) - try : - GMSH = MESH_2.Tetrahedron(algo=smeshBuilder.GMSH) - except : - MESSAGE += "\nImpossible d'utiliser "+TEXTE - ERROR += 1 + # GMSH for windows not yet implemented BOS #18709 + if platform.system() != "Windows" : + TEXTE = "Gmsh" + MESH_2 = smesh.Mesh(BOX) + smesh.SetName(MESH_2.GetMesh(), "M_"+TEXTE) + try : + GMSH = MESH_2.Tetrahedron(algo=smeshBuilder.GMSH) + except : + MESSAGE += "\nImpossible d'utiliser "+TEXTE + ERROR += 1 + else : + if ComputeMeshes : + smesh.SetName(GMSH.GetAlgorithm(), TEXTE) + OK_COMPUTE = MESH_2.Compute() + if not OK_COMPUTE : + MESSAGE += "\nErreur avec "+TEXTE + ERROR += 1 + else : + print(TEXTE+": OK") else : - if ComputeMeshes : - smesh.SetName(GMSH.GetAlgorithm(), TEXTE) - OK_COMPUTE = MESH_2.Compute() - if not OK_COMPUTE : - MESSAGE += "\nErreur avec "+TEXTE - ERROR += 1 - else : - print(TEXTE+": OK") + print("Skipping B.2 on windows") # B.3. MG_CADSurf TEXTE = "MG_CADSurf" diff --git a/doc/salome/examples/tests.set b/doc/salome/examples/tests.set index ec4a639a1..5382b5e9f 100644 --- a/doc/salome/examples/tests.set +++ b/doc/salome/examples/tests.set @@ -43,9 +43,7 @@ SET(BAD_TESTS quality_controls_ex22.py viewing_meshes_ex01.py radial_prism_3d_algo.py - test_smeshplugin_mg_tetra_parallele.py test_smeshplugins.py - MGAdaptTests_without_session.py blocFissure_01_without_session.py blocFissure_02_without_session.py blocFissure_03_without_session.py @@ -55,6 +53,13 @@ SET(BAD_TESTS blocFissure_07_without_session.py ) +IF(NOT WIN32) + LIST(APPEND BAD_TESTS + MGAdaptTests_without_session.py + test_smeshplugin_mg_tetra_parallele.py + ) +ENDIF(NOT WIN32) + SET(GOOD_TESTS cartesian_algo.py create_penta_biquad.py @@ -199,6 +204,8 @@ set(SESSION_FREE_TESTS basic_shaper_smesh_without_session.py shaper_smesh_groups_without_session.py basic_smesh_output_with_mc_field.py + ssl_hdf5_symbols_conflicts.py + doublenodes_polyhedra.py ) SET(EXAMPLES_TESTS ${BAD_TESTS} ${GOOD_TESTS} ${SESSION_FREE_TESTS} testme.py) diff --git a/doc/salome/examples/transforming_meshes_ex13.py b/doc/salome/examples/transforming_meshes_ex13.py index 94b6f7f22..d4b553963 100644 --- a/doc/salome/examples/transforming_meshes_ex13.py +++ b/doc/salome/examples/transforming_meshes_ex13.py @@ -33,6 +33,10 @@ group = mesh.Group( faces[1] ) vec = geompy.MakeVectorDXDYDZ( 1, 1, 1 ) +# ============ +# Reorient2D() +# ============ + # Each of arguments of Reorient2D() function can be of different types: # # 2DObject - the whole mesh @@ -53,6 +57,19 @@ mesh.Reorient2D( group, smesh.MakeDirStruct( -10, 1, 10 ), [0,0,0]) # FaceOrPoint - a SMESH.PointStruct structure mesh.Reorient2D( localAlgo.GetSubMesh().GetIDs(), [10,1,0], SMESH.PointStruct(0,0,0)) +# ======================== +# Reorient2DByNeighbours() +# ======================== + +# Use faces of 'group' as a reference to reorient equally all faces +mesh.Reorient2DByNeighbours([mesh], [group]) + +# Orient equally face on 'group', but not define which orientation is correct +mesh.Reorient2DByNeighbours([group]) + +# ================= +# Reorient2DBy3D() +# ================= # Use Reorient2DBy3D() to orient faces of 2 geom faces to have their normal pointing inside volumes diff --git a/doc/salome/gui/SMESH/images/reorient_2d_refgroup.png b/doc/salome/gui/SMESH/images/reorient_2d_refgroup.png new file mode 100644 index 000000000..f080f460b Binary files /dev/null and b/doc/salome/gui/SMESH/images/reorient_2d_refgroup.png differ diff --git a/doc/salome/gui/SMESH/images/reorient_faces_point.png b/doc/salome/gui/SMESH/images/reorient_faces_point.png new file mode 100644 index 000000000..63fae7233 Binary files /dev/null and b/doc/salome/gui/SMESH/images/reorient_faces_point.png differ diff --git a/doc/salome/gui/SMESH/images/reorient_faces_ref_groups.png b/doc/salome/gui/SMESH/images/reorient_faces_ref_groups.png new file mode 100644 index 000000000..f9cf53bd9 Binary files /dev/null and b/doc/salome/gui/SMESH/images/reorient_faces_ref_groups.png differ diff --git a/doc/salome/gui/SMESH/images/reorient_faces_volume.png b/doc/salome/gui/SMESH/images/reorient_faces_volume.png new file mode 100644 index 000000000..e58bdb6dc Binary files /dev/null and b/doc/salome/gui/SMESH/images/reorient_faces_volume.png differ diff --git a/doc/salome/gui/SMESH/input/about_meshes.rst b/doc/salome/gui/SMESH/input/about_meshes.rst index abb80677f..270fbe5e1 100644 --- a/doc/salome/gui/SMESH/input/about_meshes.rst +++ b/doc/salome/gui/SMESH/input/about_meshes.rst @@ -23,7 +23,7 @@ Mesh module provides several ways to create the mesh: * Bottom-up way, using :ref:`mesh modification ` operations, especially :ref:`extrusion ` and :ref:`revolution `. To create an empty mesh not based on geometry, use the same dialog as to :ref:`construct the mesh on geometry ` but specify neither the geometry nor meshing algorithms. -* The mesh can be :ref:`imported ` from (and exported to) the file in MED, UNV, STL, CGNS, DAT, GMF and SAUVE formats. +* The mesh can be :ref:`imported ` from (and exported to) the file in MED, UNV, STL, CGNS, DAT and GMF formats. * The 3D mesh can be generated from the 2D mesh not based on geometry, which was either :ref:`imported ` or created in other way. To setup the meshing parameters of a mesh not based on geometry, just invoke :ref:`Edit mesh / sub-mesh ` command on your 2D mesh. diff --git a/doc/salome/gui/SMESH/input/importing_exporting_meshes.rst b/doc/salome/gui/SMESH/input/importing_exporting_meshes.rst index b4ab4d4bd..fe9aa27f1 100644 --- a/doc/salome/gui/SMESH/input/importing_exporting_meshes.rst +++ b/doc/salome/gui/SMESH/input/importing_exporting_meshes.rst @@ -8,7 +8,6 @@ Importing and exporting meshes In MESH there is a functionality allowing import/export of meshes in the following formats: * **MED**, -* **SAUV** (format of the CASTEM code), * **UNV** (I-DEAS 10), * **STL**, * **CGNS**, @@ -45,7 +44,7 @@ If you try to export a group, the warning will be shown: Only MED format supports all types of elements that can be created in the module. If you export a mesh or group that includes elements of types that are not supported by chosen format, you will be warned about that. -There are additional parameters available at export to MED and SAUV format files. +There are additional parameters available at export to MED format files. .. _export_auto_groups: diff --git a/doc/salome/gui/SMESH/input/modules.rst b/doc/salome/gui/SMESH/input/modules.rst index 88d2d2dc4..41915c4f1 100644 --- a/doc/salome/gui/SMESH/input/modules.rst +++ b/doc/salome/gui/SMESH/input/modules.rst @@ -25,13 +25,11 @@ Importing and exporting meshes smeshBuilder.CreateMeshesFromSTL smeshBuilder.CreateMeshesFromCGNS smeshBuilder.CreateMeshesFromGMF - smeshBuilder.CreateMeshesFromSAUV Mesh.ExportMED Mesh.ExportUNV Mesh.ExportSTL Mesh.ExportCGNS Mesh.ExportDAT - Mesh.ExportSAUV Mesh.ExportGMF @@ -451,6 +449,7 @@ Changing orientation of elements Mesh.Reorient Mesh.ReorientObject Mesh.Reorient2D + Mesh.Reorient2DByNeighbours Mesh.Reorient2DBy3D Uniting triangles diff --git a/doc/salome/gui/SMESH/input/reorient_faces.rst b/doc/salome/gui/SMESH/input/reorient_faces.rst index 82982dd9a..87d510007 100644 --- a/doc/salome/gui/SMESH/input/reorient_faces.rst +++ b/doc/salome/gui/SMESH/input/reorient_faces.rst @@ -6,22 +6,33 @@ Orient faces ************ This operation allows fixing the orientation of a set of faces in the following ways: - + * The required orientation of a set of neighboring faces can be defined by a vector giving the direction of a normal to a certain face. Since the direction of face normals in the set can be even opposite, it is necessary to specify a *control* face, the normal to which will be compared with the vector. This face can be either: * found by proximity to a given point, or * specified explicitly. +* The required orientation is given by faces of specified reference groups or/and sub-meshes. The reference groups can be omitted, then orientation of an arbitrary selected face to orient defines common orientation. * Alternatively, the faces can be oriented relatively to the adjacent volumes. The orientation of a face is changed by reverting the order of its nodes. *To set orientation of faces:* -.. |img| image:: ../images/reorient_faces_face.png +.. |imgfac| image:: ../images/reorient_faces_face.png +.. |imgpnt| image:: ../images/reorient_faces_point.png +.. |imggrp| image:: ../images/reorient_faces_ref_groups.png +.. |imgvol| image:: ../images/reorient_faces_volume.png -#. In the **Modification** menu select **Reorient faces** item or click *"Reorient faces"* button |img| in the toolbar. +#. In the **Modification** menu select **Reorient faces** item or click *"Reorient faces"* button |imgfac| in the toolbar. #. In the "Reorient faces" dialog box - * Select the **Object** (mesh, sub-mesh or group) containing faces to reorient, in the Object Browser or in the 3D Viewer. + * Select a way to define orientation: + + * |imgpnt| - by specifying a point and a vector + * |imgfac| - by specifying a face and a vector + * |imggrp| - by specifying reference face groups + * |imgvol| - by specifying reference volume groups + + * Select the **Object(s)** (mesh, groups and/or sub-meshes) containing faces to reorient, in the Object Browser or in the 3D Viewer. * To reorient by direction of the face normal: * Specify the coordinates of the **Point** by which the control face will be found. You can specify the **Point** by picking a node in the 3D Viewer or selecting a vertex in the Object Browser. @@ -37,7 +48,7 @@ The orientation of a face is changed by reverting the order of its nodes. .. centered:: The orientation of adjacent faces is chosen according to a vector. The control face is found by point. - * In the second mode it is possible to pick the **Face** by mouse in the 3D Viewer or directly input the **Face** ID in the corresponding field. + * In the second mode it is possible to pick the **Face** by mouse in the 3D Viewer or directly enter the **Face** ID in the corresponding field. .. image:: ../images/reorient_2d_face.png :align: center @@ -46,16 +57,27 @@ The orientation of a face is changed by reverting the order of its nodes. The orientation of adjacent faces is chosen according to a vector. The control face is explicitly given. - * In the third mode, the faces can be reoriented according to volumes: + * In the third mode, the faces can be reoriented equally to reference faces: + + * If necessary, select 2D **Reference objects** (groups or/and sub-meshes) containing the reference faces, in the Object Browser or in the 3D Viewer. This field can be left empty, then orientation of an arbitrary face will be used as a reference. + + + .. image:: ../images/reorient_2d_refgroup.png + :align: center + + .. centered:: + The orientation of faces is given by reference face groups and/or sub-meshes. + + * In the fourth mode, the faces can be reoriented according to volumes: * Select an object (mesh, sub-mesh or group) containing reference **Volumes**, in the Object Browser or in the 3D Viewer. * Specify whether face normals should point outside or inside the reference volumes using **Face normal outside volume** check-box. - .. image:: ../images/reorient_2d_volume.png - :align: center + .. image:: ../images/reorient_2d_volume.png + :align: center - .. centered:: - The orientation of faces is chosen relatively to adjacent volumes. + .. centered:: + The orientation of faces is chosen relatively to adjacent volumes. #. Click the **Apply** or **Apply and Close** button to confirm the operation. diff --git a/idl/SMESH_Gen.idl b/idl/SMESH_Gen.idl index d5772802b..cfdca30f1 100644 --- a/idl/SMESH_Gen.idl +++ b/idl/SMESH_Gen.idl @@ -253,16 +253,9 @@ module SMESH /*! * Create Mesh object(s) importing data from given MED file */ - mesh_array CreateMeshesFromMED( in string theFileName, - out SMESH::DriverMED_ReadStatus theStatus ) - raises ( SALOME::SALOME_Exception ); - - /*! - * Create Mesh object(s) importing data from given MED file - */ - mesh_array CreateMeshesFromSAUV( in string theFileName, - out SMESH::DriverMED_ReadStatus theStatus ) - raises ( SALOME::SALOME_Exception ); + mesh_array CreateMeshesFromMED( in string theFileName, + out SMESH::DriverMED_ReadStatus theStatus ) + raises ( SALOME::SALOME_Exception ); /*! * Create Mesh object importing data from given STL file diff --git a/idl/SMESH_Mesh.idl b/idl/SMESH_Mesh.idl index 7ee04ecee..49e8f97cb 100644 --- a/idl/SMESH_Mesh.idl +++ b/idl/SMESH_Mesh.idl @@ -714,18 +714,11 @@ module SMESH in double ZTolerance, in boolean saveNumbers) raises (SALOME::SALOME_Exception); - /*! - * Export Mesh to SAUV formatted file - * Write a temporary med file and use med2sauv - */ - void ExportSAUV( in string file, in boolean auto_groups ) - raises (SALOME::SALOME_Exception); - /*! * Return string representation of a MED file version comprising nbDigits */ string GetVersionString(in long minor, in short nbDigits); - + /*! * Return the list of med versions compatibles for write/append, * encoded in 10*major+minor (for instance, code for med 3.2.1 is 32) diff --git a/idl/SMESH_MeshEditor.idl b/idl/SMESH_MeshEditor.idl index 26e73dfaf..69f159dc2 100644 --- a/idl/SMESH_MeshEditor.idl +++ b/idl/SMESH_MeshEditor.idl @@ -318,6 +318,19 @@ module SMESH in DirStruct theDirection, in long theFace, in PointStruct thePoint) raises (SALOME::SALOME_Exception); + /*! + * \brief Reorient faces contained in a list of \a objectFaces + * equally to faces contained in a list of \a referenceFaces. + * \param objectFaces - faces to reorient in a list including either + * the whole mesh or groups and/or sub-meshes. + * \param referenceFaces - correctly oriented faces in a list of groups and/or sub-meshes. + * It can be empty, then the 1st face in \a objectFaces is used as the reference. + * \return number of reoriented faces. + */ + long Reorient2DByNeighbours(in SMESH::ListOfIDSources objectFaces, + in SMESH::ListOfIDSources referenceFaces) + raises (SALOME::SALOME_Exception); + /*! * \brief Reorient faces basing on orientation of adjacent volumes. * \param faces - a list of objects containing face to reorient @@ -338,6 +351,7 @@ module SMESH * is still performed; theMaxAngle is measured in radians. * \return \c true in case of success, FALSE otherwise. */ + boolean TriToQuad (in smIdType_array IDsOfElements, in NumericalFunctor Criterion, in double MaxAngle) raises (SALOME::SALOME_Exception); diff --git a/resources/CMakeLists.txt b/resources/CMakeLists.txt index 6c6c90d80..7e0d62012 100644 --- a/resources/CMakeLists.txt +++ b/resources/CMakeLists.txt @@ -236,6 +236,7 @@ SET(SMESH_RESOURCES_FILES pattern_sample_3D.png reorient_faces_face.png reorient_faces_point.png + reorient_faces_ref_groups.png reorient_faces_volume.png scale.png scale_along_axes.png diff --git a/resources/reorient_faces_ref_groups.png b/resources/reorient_faces_ref_groups.png new file mode 100644 index 000000000..f9cf53bd9 Binary files /dev/null and b/resources/reorient_faces_ref_groups.png differ diff --git a/src/DriverGMF/DriverGMF_Read.cxx b/src/DriverGMF/DriverGMF_Read.cxx index 175d8100d..c85abbf3c 100644 --- a/src/DriverGMF/DriverGMF_Read.cxx +++ b/src/DriverGMF/DriverGMF_Read.cxx @@ -537,3 +537,37 @@ Driver_Mesh::Status DriverGMF_Read::storeBadNodeIds(const char* gmfKwd, int elem } return DRS_OK; } + +//================================================================================ +/*! + * \brief Return number of mesh entities in a file + */ +//================================================================================ + +bool DriverGMF_Read::GetMeshInfo(smIdType & nbNodes, + smIdType & nbEdges, + smIdType & nbFaces, + smIdType & nbVols) +{ + nbNodes = nbEdges = nbFaces = nbVols = 0; + + Kernel_Utils::Localizer loc; + + int dim, version; + int meshID = GmfOpenMesh( myFile.c_str(), GmfRead, &version, &dim ); + if ( !meshID ) + return false; + + DriverGMF::MeshCloser aMeshCloser( meshID ); // An object closing GMF mesh at destruction + + nbNodes = GmfStatKwd(meshID, GmfVertices ); + nbEdges = GmfStatKwd(meshID, GmfEdges ); + nbFaces = ( GmfStatKwd(meshID, GmfTriangles ) + + GmfStatKwd(meshID, GmfQuadrilaterals )); + nbVols = ( GmfStatKwd(meshID, GmfTetrahedra ) + + GmfStatKwd(meshID, GmfPyramids ) + + GmfStatKwd(meshID, GmfHexahedra ) + + GmfStatKwd(meshID, GmfPrisms )); + + return true; +} diff --git a/src/DriverGMF/DriverGMF_Read.hxx b/src/DriverGMF/DriverGMF_Read.hxx index f055f54b7..8464a5345 100644 --- a/src/DriverGMF/DriverGMF_Read.hxx +++ b/src/DriverGMF/DriverGMF_Read.hxx @@ -57,6 +57,11 @@ public: virtual Status Perform(); + bool GetMeshInfo(smIdType & nbVertex, + smIdType & nbEdge, + smIdType & nbFace, + smIdType & nbVol); + private: Status storeBadNodeIds(const char* gmfKwd, int elemNb, int nb, ...); diff --git a/src/DriverMED/DriverMED_W_SMESHDS_Mesh.cxx b/src/DriverMED/DriverMED_W_SMESHDS_Mesh.cxx index 5076ae51d..844e37238 100644 --- a/src/DriverMED/DriverMED_W_SMESHDS_Mesh.cxx +++ b/src/DriverMED/DriverMED_W_SMESHDS_Mesh.cxx @@ -166,21 +166,6 @@ void DriverMED_W_SMESHDS_Mesh::AddGroupOfBalls() myDoGroupOfBalls = true; } -//================================================================================ -/*! - * \brief Set up a flag to add all elements not belonging to any group to - * some auxiliary group. This is needed for SMESH -> SAUVE -> SMESH conversion, - * which since PAL0023285 reads only SAUVE elements belonging to any group, - * and hence can lose some elements. That auxiliary group is ignored while - * reading a MED file. - */ -//================================================================================ - -void DriverMED_W_SMESHDS_Mesh::AddAllToGroup() -{ - myDoAllInGroups = true; -} - namespace { diff --git a/src/DriverMED/DriverMED_W_SMESHDS_Mesh.h b/src/DriverMED/DriverMED_W_SMESHDS_Mesh.h index 43e5c2745..fc8cf9b15 100644 --- a/src/DriverMED/DriverMED_W_SMESHDS_Mesh.h +++ b/src/DriverMED/DriverMED_W_SMESHDS_Mesh.h @@ -64,7 +64,6 @@ class MESHDRIVERMED_EXPORT DriverMED_W_SMESHDS_Mesh: public Driver_SMESHDS_Mesh void AddGroupOfVolumes(); void AddGroupOf0DElems(); void AddGroupOfBalls(); - void AddAllToGroup(); /*! functions to prepare adding one mesh */ diff --git a/src/SMDS/SMDS_ElementFactory.cxx b/src/SMDS/SMDS_ElementFactory.cxx index c3ab97c8c..611511916 100644 --- a/src/SMDS/SMDS_ElementFactory.cxx +++ b/src/SMDS/SMDS_ElementFactory.cxx @@ -230,6 +230,18 @@ smIdType SMDS_ElementFactory::FromVtkToSmds( vtkIdType vtkID ) return vtkID + 1; } +//================================================================================ +/*! + * \brief Clear marked flag of all elements + */ +//================================================================================ + +void SMDS_ElementFactory::SetAllNotMarked() +{ + for ( SMDS_ElementChunk& chunk : myChunks ) + chunk.SetAllNotMarked(); +} + //================================================================================ /*! * \brief Mark the element as non-used @@ -727,6 +739,17 @@ void SMDS_ElementChunk::SetIsMarked( const SMDS_MeshElement* e, bool is ) myMarkedSet[ Index( e )] = is; } +//================================================================================ +/*! + * \brief Clear marked flag of all elements + */ +//================================================================================ + +void SMDS_ElementChunk::SetAllNotMarked() +{ + clearVector( myMarkedSet ); +} + //================================================================================ /*! * \brief Return SMDS_Position of a node on a shape diff --git a/src/SMDS/SMDS_ElementFactory.hxx b/src/SMDS/SMDS_ElementFactory.hxx index dcc00a307..92f22e55a 100644 --- a/src/SMDS/SMDS_ElementFactory.hxx +++ b/src/SMDS/SMDS_ElementFactory.hxx @@ -116,6 +116,8 @@ public: boost::shared_ptr< ElemIterator > GetShapeIterator( int shapeID, size_t nbElemsToReturn, const SMDS_MeshElement* sm1stElem ); + //! Clear marked flag of all elements + void SetAllNotMarked(); //! Mark the element as non-used void Free( const SMDS_MeshElement* ); @@ -441,6 +443,7 @@ public: bool IsMarked ( const SMDS_MeshElement* e ) const; void SetIsMarked( const SMDS_MeshElement* e, bool is ); + void SetAllNotMarked(); SMDS_PositionPtr GetPosition( const SMDS_MeshNode* n ) const; void SetPosition( const SMDS_MeshNode* n, const SMDS_PositionPtr& pos, int shapeID ); diff --git a/src/SMDS/SMDS_Mesh.cxx b/src/SMDS/SMDS_Mesh.cxx index 2e9924295..d26107218 100644 --- a/src/SMDS/SMDS_Mesh.cxx +++ b/src/SMDS/SMDS_Mesh.cxx @@ -1052,6 +1052,26 @@ bool SMDS_Mesh::RemoveSubMesh(const SMDS_Mesh * aMesh) return found; } +//======================================================================= +//function : SetAllNodesNotMarked +//purpose : Clear marked flag of all nodes +//======================================================================= + +void SMDS_Mesh::SetAllNodesNotMarked() +{ + myNodeFactory->SetAllNotMarked(); +} + +//======================================================================= +//function : SetAllCellsNotMarked +//purpose : Clear marked flag of all cells +//======================================================================= + +void SMDS_Mesh::SetAllCellsNotMarked() +{ + myCellFactory->SetAllNotMarked(); +} + //======================================================================= //function : ChangePolyhedronNodes //purpose : diff --git a/src/SMDS/SMDS_Mesh.hxx b/src/SMDS/SMDS_Mesh.hxx index c76f7d277..de50492f9 100644 --- a/src/SMDS/SMDS_Mesh.hxx +++ b/src/SMDS/SMDS_Mesh.hxx @@ -618,6 +618,9 @@ public: const std::vector& nodes, const std::vector& quantities); + void SetAllNodesNotMarked(); + void SetAllCellsNotMarked(); + //virtual void Renumber (const bool isNodes, const int startID = 1, const int deltaID = 1); // Renumber all nodes or elements. diff --git a/src/SMESH/MG_ADAPT.cxx b/src/SMESH/MG_ADAPT.cxx index 8f2a36a44..27a57c894 100644 --- a/src/SMESH/MG_ADAPT.cxx +++ b/src/SMESH/MG_ADAPT.cxx @@ -19,8 +19,11 @@ #include "MG_ADAPT.hxx" -#include "SMESH_File.hxx" -#include "SMESH_Comment.hxx" +#include +#include +#include +#include +#include #include #include @@ -320,7 +323,7 @@ MgAdaptHypothesisData* MgAdapt::getData() const } void MgAdapt::setMedFileIn(std::string fileName) { - if ( isFileExist(fileName) ) + if ( isFileExist( fileName )) { medFileIn = fileName; @@ -1006,7 +1009,7 @@ std::string MgAdapt::getCommandToRun() cmd += " --"; else cmd += " "; -// std::cout << "--- option: '" << option << ", value: '" << value <<"'"<< std::endl; + // std::cout << "--- option: '" << option << ", value: '" << value <<"'"<< std::endl; cmd += option + " " + value; } } @@ -1016,13 +1019,31 @@ std::string MgAdapt::getCommandToRun() { cmd+= " --verbose "+ ToComment(verbosityLevel); } - //~} -//~cmd+= " >" + // get license key + { + smIdType nbVertex, nbEdge, nbFace, nbVol; + DriverGMF_Read gmfReader; + gmfReader.SetFile( meshIn ); + gmfReader.GetMeshInfo( nbVertex, nbEdge, nbFace, nbVol ); + + std::string errorTxt; + std::string key = SMESHUtils_MGLicenseKeyGen::GetKey( meshIn, + FromSmIdType( nbVertex ), + FromSmIdType( nbEdge ), + FromSmIdType( nbFace ), + FromSmIdType( nbVol ), + errorTxt ); + if ( key.empty() ) + return ToComment( "Problem with library SalomeMeshGemsKeyGenerator: " + errorTxt ); + + cmd += " --key " + key; + } + #ifdef WIN32 - cmd += " < NUL"; + cmd += " < NUL"; #endif -// std::cout << "--- cmd :"<< std::endl; -// std::cout << cmd << std::endl; + // std::cout << "--- cmd :"<< std::endl; + // std::cout << cmd << std::endl; return cmd; } @@ -1074,7 +1095,9 @@ std::string MgAdapt::defaultWorkingDirectory() { aTmpDir = Tmp_dir; } - else { + + if ( ! isFileExist( aTmpDir )) + { #ifdef WIN32 aTmpDir = "C:\\"; #else @@ -1381,8 +1404,17 @@ void MgAdapt::convertMedFile(std::string& meshFormatMeshFileName, std::string& s checkTimeStepRank(medFileIn) ; MEDCoupling::MCAuto fts( mfd->getFields()->getFieldWithName(fieldName) ); MEDCoupling::MCAuto f = fts->getTimeStep(timeStep, rank); - MEDCoupling::MCAuto tmFts = MEDCoupling::MEDFileFieldMultiTS::New(); - tmFts->pushBackTimeStep(f); + MEDCoupling::MCAuto tmFts = MEDCoupling::DynamicCast(fts); + + // if not able to cast to double field, try float field + if (!tmFts) + { + MEDCoupling::MCAuto tmFtsFloat = MEDCoupling::DynamicCast(fts); + if (!tmFtsFloat) + THROW_SALOME_EXCEPTION("\nUnexpected field type.\n"); + // convert float field to double + tmFts = tmFtsFloat->convertToDouble(); + } fields->pushField(tmFts); diff --git a/src/SMESH/SMESH_Gen.cxx b/src/SMESH/SMESH_Gen.cxx index 65e59d98d..db4fe2136 100644 --- a/src/SMESH/SMESH_Gen.cxx +++ b/src/SMESH/SMESH_Gen.cxx @@ -40,7 +40,6 @@ #include "SMESH_subMesh.hxx" #include "utilities.h" -#include "OpUtil.hxx" #include "Utils_ExceptHandlers.hxx" #include @@ -376,7 +375,7 @@ bool SMESH_Gen::Compute(SMESH_Mesh & aMesh, const TopoDS_Shape& aSubShape = smToCompute->GetSubShape(); const int aShapeDim = GetShapeDim( aSubShape ); - if ( aShapeDim < 1 || aSubShape.ShapeType() == shapeType ) + if ( aShapeDim < 1 || aSubShape.ShapeType() <= shapeType ) continue; // check for preview dimension limitations diff --git a/src/SMESH/SMESH_Mesh.cxx b/src/SMESH/SMESH_Mesh.cxx index 7c634c4de..f03468977 100644 --- a/src/SMESH/SMESH_Mesh.cxx +++ b/src/SMESH/SMESH_Mesh.cxx @@ -1416,8 +1416,7 @@ void SMESH_Mesh::exportMEDCommmon(DriverMED_W_SMESHDS_Mesh& theWriter, bool theAutoDimension, bool theAddODOnVertices, double theZTolerance, - bool theSaveNumbers, - bool theAllElemsToGroup) + bool theSaveNumbers) { Driver_Mesh::Status status = Driver_Mesh::DRS_OK; @@ -1443,8 +1442,6 @@ void SMESH_Mesh::exportMEDCommmon(DriverMED_W_SMESHDS_Mesh& theWriter, theWriter.AddGroupOf0DElems(); theWriter.AddGroupOfBalls(); } - if ( theAllElemsToGroup ) - theWriter.AddAllToGroup(); // Pass groups to writer. Provide unique group names. //set aGroupNames; // Corrected for Mantis issue 0020028 @@ -1499,8 +1496,7 @@ SMESH_Mesh::ExportMEDCoupling(const char* theMeshName, { DriverMED_W_SMESHDS_Mesh_Mem writer; this->exportMEDCommmon( writer, theMeshName, theAutoGroups, theMeshPart, theAutoDimension, - theAddODOnVertices, theZTolerance, theSaveNumbers, - /*AllElemsToGroup(for ExportSAUV())=*/false); + theAddODOnVertices, theZTolerance, theSaveNumbers); return writer.getData(); } @@ -1525,8 +1521,6 @@ SMESH_Mesh::ExportMEDCoupling(const char* theMeshName, * 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 */ //================================================================================ @@ -1539,65 +1533,12 @@ void SMESH_Mesh::ExportMED(const char * theFile, bool theAutoDimension, bool theAddODOnVertices, double theZTolerance, - bool theSaveNumbers, - bool theAllElemsToGroup) + bool theSaveNumbers) { 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 *theFile, - const char* theMeshName, - bool theAutoGroups) -{ - std::string medfilename( theFile ); - medfilename += ".med"; - std::string cmd; -#ifdef WIN32 - cmd = "%PYTHONBIN% "; -#else - cmd = "python3 "; -#endif - cmd += "-c \""; - cmd += "from medutilities import my_remove ; my_remove(r'" + medfilename + "')"; - cmd += "\""; - system(cmd.c_str()); - try { - 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 ) - { - throw TooLargeForExport("SAUV"); - } -#ifdef WIN32 - cmd = "%PYTHONBIN% "; -#else - cmd = "python3 "; -#endif - cmd += "-c \""; - cmd += "from medutilities import convert ; convert(r'" + medfilename + "', 'MED', 'GIBI', 1, r'" + theFile + "')"; - cmd += "\""; - system(cmd.c_str()); -#ifdef WIN32 - cmd = "%PYTHONBIN% "; -#else - cmd = "python3 "; -#endif - cmd += "-c \""; - cmd += "from medutilities import my_remove ; my_remove(r'" + medfilename + "')"; - cmd += "\""; - system(cmd.c_str()); + this->exportMEDCommmon( writer, theMeshName, theAutoGroups, theMeshPart, theAutoDimension, theAddODOnVertices, theZTolerance, theSaveNumbers ); } //================================================================================ diff --git a/src/SMESH/SMESH_Mesh.hxx b/src/SMESH/SMESH_Mesh.hxx index 81495db9c..927aa4047 100644 --- a/src/SMESH/SMESH_Mesh.hxx +++ b/src/SMESH/SMESH_Mesh.hxx @@ -282,8 +282,7 @@ class SMESH_EXPORT SMESH_Mesh bool theAutoDimension = false, bool theAddODOnVertices = false, double theZTolerance = -1., - bool theSaveNumbers = true, - bool theAllElemsToGroup = false); + bool theSaveNumbers = true); void ExportDAT(const char * file, const SMESHDS_Mesh* meshPart = 0, @@ -302,9 +301,6 @@ class SMESH_EXPORT SMESH_Mesh void ExportGMF(const char * file, const SMESHDS_Mesh* mesh, bool withRequiredGroups = true ); - void ExportSAUV(const char *file, - const char* theMeshName = NULL, - bool theAutoGroups = true); double GetComputeProgress() const; @@ -395,8 +391,7 @@ private: bool theAutoDimension, bool theAddODOnVertices, double theZTolerance, - bool theSaveNumbers, - bool theAllElemsToGroup); + bool theSaveNumbers); private: void fillAncestorsMap(const TopoDS_Shape& theShape); diff --git a/src/SMESH/SMESH_MeshEditor.cxx b/src/SMESH/SMESH_MeshEditor.cxx index ff121002f..853d59b3e 100644 --- a/src/SMESH/SMESH_MeshEditor.cxx +++ b/src/SMESH/SMESH_MeshEditor.cxx @@ -1161,69 +1161,88 @@ bool SMESH_MeshEditor::Reorient (const SMDS_MeshElement * theElem) /*! * \brief Reorient faces. * \param theFaces - the faces to reorient. If empty the whole mesh is meant - * \param theDirection - desired direction of normal of \a theFace - * \param theFace - one of \a theFaces that should be oriented according to - * \a theDirection and whose orientation defines orientation of other faces + * \param theDirection - desired direction of normal of \a theRefFaces. + * It can be (0,0,0) in order to keep orientation of \a theRefFaces. + * \param theRefFaces - correctly oriented faces whose orientation defines + * orientation of other faces. * \return number of reoriented faces. */ //================================================================================ -int SMESH_MeshEditor::Reorient2D (TIDSortedElemSet & theFaces, - const gp_Dir& theDirection, - const SMDS_MeshElement * theFace) +int SMESH_MeshEditor::Reorient2D( TIDSortedElemSet & theFaces, + const gp_Vec& theDirection, + TIDSortedElemSet & theRefFaces, + bool theAllowNonManifold ) { int nbReori = 0; - if ( !theFace || theFace->GetType() != SMDSAbs_Face ) return nbReori; if ( theFaces.empty() ) { - SMDS_FaceIteratorPtr fIt = GetMeshDS()->facesIterator(/*idInceasingOrder=true*/); + SMDS_FaceIteratorPtr fIt = GetMeshDS()->facesIterator(); while ( fIt->more() ) theFaces.insert( theFaces.end(), fIt->next() ); + + if ( theFaces.empty() ) + return nbReori; } - // orient theFace according to theDirection - gp_XYZ normal; - SMESH_MeshAlgos::FaceNormal( theFace, normal, /*normalized=*/false ); - if ( normal * theDirection.XYZ() < 0 ) - nbReori += Reorient( theFace ); + // orient theRefFaces according to theDirection + if ( theDirection.X() != 0 || theDirection.Y() != 0 || theDirection.Z() != 0 ) + for ( const SMDS_MeshElement* refFace : theRefFaces ) + { + gp_XYZ normal; + SMESH_MeshAlgos::FaceNormal( refFace, normal, /*normalized=*/false ); + if ( normal * theDirection.XYZ() < 0 ) + nbReori += Reorient( refFace ); + } - // Orient other faces + // mark reference faces + GetMeshDS()->SetAllCellsNotMarked(); + for ( const SMDS_MeshElement* refFace : theRefFaces ) + refFace->setIsMarked( true ); - set< const SMDS_MeshElement* > startFaces, visitedFaces; - TIDSortedElemSet avoidSet; - set< SMESH_TLink > checkedLinks; - pair< set< SMESH_TLink >::iterator, bool > linkIt_isNew; + // erase reference faces from theFaces + for ( TIDSortedElemSet::iterator fIt = theFaces.begin(); fIt != theFaces.end(); ) + if ( (*fIt)->isMarked() ) + fIt = theFaces.erase( fIt ); + else + ++fIt; - if ( theFaces.size() > 1 )// leave 1 face to prevent finding not selected faces - theFaces.erase( theFace ); - startFaces.insert( theFace ); + if ( theRefFaces.empty() ) + { + theRefFaces.insert( *theFaces.begin() ); + theFaces.erase( theFaces.begin() ); + } + + // Orient theFaces + + // if ( theFaces.size() > 1 )// leave 1 face to prevent finding not selected faces + // theFaces.erase( theFace ); int nodeInd1, nodeInd2; - const SMDS_MeshElement* otherFace; + const SMDS_MeshElement* refFace, *otherFace; vector< const SMDS_MeshElement* > facesNearLink; vector< std::pair< int, int > > nodeIndsOfFace; + TIDSortedElemSet avoidSet, emptySet; + NCollection_Map< SMESH_TLink, SMESH_TLink > checkedLinks; - set< const SMDS_MeshElement* >::iterator startFace = startFaces.begin(); - while ( !startFaces.empty() ) + while ( !theRefFaces.empty() ) { - startFace = startFaces.begin(); - theFace = *startFace; - startFaces.erase( startFace ); - if ( !visitedFaces.insert( theFace ).second ) - continue; + auto refFaceIt = theRefFaces.begin(); + refFace = *refFaceIt; + theRefFaces.erase( refFaceIt ); avoidSet.clear(); - avoidSet.insert(theFace); + avoidSet.insert( refFace ); - NLink link( theFace->GetNode( 0 ), (SMDS_MeshNode *) 0 ); + NLink link( refFace->GetNode( 0 ), nullptr ); - const int nbNodes = theFace->NbCornerNodes(); - for ( int i = 0; i < nbNodes; ++i ) // loop on links of theFace + const int nbNodes = refFace->NbCornerNodes(); + for ( int i = 0; i < nbNodes; ++i ) // loop on links of refFace { - link.second = theFace->GetNode(( i+1 ) % nbNodes ); - linkIt_isNew = checkedLinks.insert( link ); - if ( !linkIt_isNew.second ) + link.second = refFace->GetNode(( i+1 ) % nbNodes ); + bool isLinkVisited = checkedLinks.Contains( link ); + if ( isLinkVisited ) { // link has already been checked and won't be encountered more // if the group (theFaces) is manifold @@ -1231,28 +1250,41 @@ int SMESH_MeshEditor::Reorient2D (TIDSortedElemSet & theFaces, } else { + checkedLinks.Add( link ); + facesNearLink.clear(); nodeIndsOfFace.clear(); + TIDSortedElemSet::iterator objFaceIt = theFaces.end(); + while (( otherFace = SMESH_MeshAlgos::FindFaceInSet( link.first, link.second, - theFaces, avoidSet, + emptySet, avoidSet, &nodeInd1, &nodeInd2 ))) - if ( otherFace != theFace) + { + if (( otherFace->isMarked() ) || // ref face + (( objFaceIt = theFaces.find( otherFace )) != theFaces.end() )) // object face { facesNearLink.push_back( otherFace ); nodeIndsOfFace.push_back( make_pair( nodeInd1, nodeInd2 )); - avoidSet.insert( otherFace ); } + avoidSet.insert( otherFace ); + } if ( facesNearLink.size() > 1 ) { // NON-MANIFOLD mesh shell ! - // select a face most co-directed with theFace, + if ( !theAllowNonManifold ) + { + throw SALOME_Exception("Non-manifold topology of groups"); + } + // select a face most co-directed with refFace, // other faces won't be visited this time gp_XYZ NF, NOF; - SMESH_MeshAlgos::FaceNormal( theFace, NF, /*normalized=*/false ); + SMESH_MeshAlgos::FaceNormal( refFace, NF, /*normalized=*/false ); double proj, maxProj = -1; - for ( size_t i = 0; i < facesNearLink.size(); ++i ) { + for ( size_t i = 0; i < facesNearLink.size(); ++i ) + { SMESH_MeshAlgos::FaceNormal( facesNearLink[i], NOF, /*normalized=*/false ); - if (( proj = Abs( NF * NOF )) > maxProj ) { + if (( proj = Abs( NF * NOF )) > maxProj ) + { maxProj = proj; otherFace = facesNearLink[i]; nodeInd1 = nodeIndsOfFace[i].first; @@ -1260,9 +1292,9 @@ int SMESH_MeshEditor::Reorient2D (TIDSortedElemSet & theFaces, } } // not to visit rejected faces - for ( size_t i = 0; i < facesNearLink.size(); ++i ) - if ( facesNearLink[i] != otherFace && theFaces.size() > 1 ) - visitedFaces.insert( facesNearLink[i] ); + // for ( size_t i = 0; i < facesNearLink.size(); ++i ) + // if ( facesNearLink[i] != otherFace && theFaces.size() > 1 ) + // visitedFaces.insert( facesNearLink[i] ); } else if ( facesNearLink.size() == 1 ) { @@ -1270,20 +1302,36 @@ int SMESH_MeshEditor::Reorient2D (TIDSortedElemSet & theFaces, nodeInd1 = nodeIndsOfFace.back().first; nodeInd2 = nodeIndsOfFace.back().second; } - if ( otherFace && otherFace != theFace) + if ( otherFace ) { - // link must be reverse in otherFace if orientation to otherFace - // is same as that of theFace - if ( abs(nodeInd2-nodeInd1) == 1 ? nodeInd2 > nodeInd1 : nodeInd1 > nodeInd2 ) + // link must be reverse in otherFace if orientation of otherFace + // is same as that of refFace + if ( abs( nodeInd2 - nodeInd1 ) == 1 ? nodeInd2 > nodeInd1 : nodeInd1 > nodeInd2 ) { + if ( otherFace->isMarked() ) + throw SALOME_Exception("Different orientation of reference faces"); nbReori += Reorient( otherFace ); } - startFaces.insert( otherFace ); + if ( !otherFace->isMarked() ) + { + theRefFaces.insert( otherFace ); + if ( objFaceIt != theFaces.end() ) + theFaces.erase( objFaceIt ); + } } } - std::swap( link.first, link.second ); // reverse the link + link.first = link.second; // reverse the link + + } // loop on links of refFace + + if ( theRefFaces.empty() && !theFaces.empty() ) + { + theRefFaces.insert( *theFaces.begin() ); + theFaces.erase( theFaces.begin() ); } - } + + } // while ( !theRefFaces.empty() ) + return nbReori; } @@ -10792,7 +10840,23 @@ bool SMESH_MeshEditor::doubleNodes(SMESHDS_Mesh* theMeshDS, if ( theIsDoubleElem ) AddElement( newNodes, elemType.Init( anElem, /*basicOnly=*/false )); else - theMeshDS->ChangeElementNodes( anElem, &newNodes[ 0 ], newNodes.size() ); + { + // change element nodes + const SMDSAbs_EntityType geomType = anElem->GetEntityType(); + if ( geomType == SMDSEntity_Polyhedra ) + { + // special treatment for polyhedron + const SMDS_MeshVolume* aPolyhedron = SMDS_Mesh::DownCast< SMDS_MeshVolume >( anElem ); + if (!aPolyhedron) { + MESSAGE("Warning: bad volumic element"); + return false; + } + theMeshDS->ChangePolyhedronNodes( anElem, newNodes, aPolyhedron->GetQuantities() ); + } + else + // standard entity type + theMeshDS->ChangeElementNodes( anElem, &newNodes[ 0 ], newNodes.size() ); + } res = true; } diff --git a/src/SMESH/SMESH_MeshEditor.hxx b/src/SMESH/SMESH_MeshEditor.hxx index e9e13f796..6962f2c2d 100644 --- a/src/SMESH/SMESH_MeshEditor.hxx +++ b/src/SMESH/SMESH_MeshEditor.hxx @@ -158,11 +158,12 @@ public: bool Reorient (const SMDS_MeshElement * theElement); // Reverse theElement orientation - int Reorient2D (TIDSortedElemSet & theFaces, - const gp_Dir& theDirection, - const SMDS_MeshElement * theFace); - // Reverse theFaces whose orientation to be same as that of theFace - // oriented according to theDirection. Return nb of reoriented faces + int Reorient2D (TIDSortedElemSet & theFaces, + const gp_Vec& theDirection, + TIDSortedElemSet & theRefFaces, + bool theAllowNonManifold); + // Reverse theFaces whose orientation to be same as that of theRefFaces + // optionally oriented according to theDirection. Return nb of reoriented faces int Reorient2DBy3D (TIDSortedElemSet & theFaces, TIDSortedElemSet & theVolumes, diff --git a/src/SMESH/SMESH_subMesh.cxx b/src/SMESH/SMESH_subMesh.cxx index 23d72c5a0..424377af7 100644 --- a/src/SMESH/SMESH_subMesh.cxx +++ b/src/SMESH/SMESH_subMesh.cxx @@ -39,7 +39,6 @@ #include "SMESH_subMeshEventListener.hxx" #include "utilities.h" -#include "OpUtil.hxx" #include "Basics_Utils.hxx" #include @@ -2209,7 +2208,7 @@ TopoDS_Shape SMESH_subMesh::getCollection(SMESH_Gen * /*theGen*/, } } - return aCompound; + return theSubs.size() == 1 ? theSubs[0]->GetSubShape() : aCompound; } //======================================================================= diff --git a/src/SMESHFiltersSelection/SMESH_Type.h b/src/SMESHFiltersSelection/SMESH_Type.h index 5aa2df226..2d2838c12 100644 --- a/src/SMESHFiltersSelection/SMESH_Type.h +++ b/src/SMESHFiltersSelection/SMESH_Type.h @@ -62,7 +62,8 @@ namespace SMESH { IDSOURCE, IDSOURCE_EDGE, // IDSource including edges IDSOURCE_FACE, - IDSOURCE_VOLUME + IDSOURCE_VOLUME, + NB_SMESH_TYPES }; } #endif diff --git a/src/SMESHGUI/SMESHGUI.cxx b/src/SMESHGUI/SMESHGUI.cxx index ca9c78767..d7b4ed744 100644 --- a/src/SMESHGUI/SMESHGUI.cxx +++ b/src/SMESHGUI/SMESHGUI.cxx @@ -239,11 +239,6 @@ namespace theCommandID == SMESHOp::OpPopupImportCGNS ) { filter.append( QObject::tr( "CGNS_FILES_FILTER" ) + " (*.cgns)" ); } - else if ( theCommandID == SMESHOp::OpImportSAUV || - theCommandID == SMESHOp::OpPopupImportSAUV ) { - filter.append( QObject::tr( "SAUV_FILES_FILTER" ) + " (*.sauv *.sauve)" ); - filter.append( QObject::tr( "ALL_FILES_FILTER" ) + " (*)" ); - } else if ( theCommandID == SMESHOp::OpImportGMF || theCommandID == SMESHOp::OpPopupImportGMF ) { filter.append( QObject::tr( "GMF_ASCII_FILES_FILTER" ) + " (*.mesh)" ); @@ -345,18 +340,6 @@ namespace } break; } - case SMESHOp::OpImportSAUV: - case SMESHOp::OpPopupImportSAUV: - { - // SAUV format - SMESH::DriverMED_ReadStatus res; - aMeshes = theComponentMesh->CreateMeshesFromSAUV( filename.toUtf8().constData(), res ); - if ( res != SMESH::DRS_OK ) { - errors.append( QString( "%1 :\n\t%2" ).arg( filename ). - arg( QObject::tr( QString( "SMESH_DRS_%1" ).arg( res ).toLatin1().data() ) ) ); - } - break; - } case SMESHOp::OpImportGMF: case SMESHOp::OpPopupImportGMF: { @@ -448,8 +431,6 @@ namespace theCommandID == SMESHOp::OpPopupExportSTL ); const bool isCGNS= ( theCommandID == SMESHOp::OpExportCGNS || theCommandID == SMESHOp::OpPopupExportCGNS ); - const bool isSAUV= ( theCommandID == SMESHOp::OpExportSAUV || - theCommandID == SMESHOp::OpPopupExportSAUV ); const bool isGMF = ( theCommandID == SMESHOp::OpExportGMF || theCommandID == SMESHOp::OpPopupExportGMF ); @@ -529,7 +510,7 @@ namespace SMESH::SMESH_Mesh_var aMesh = aMeshOrGroup->GetMesh(); QString aMeshName = (*aMeshIter).second; - if ( isMED || isCGNS || isSAUV ) // formats where group names must be unique + if ( isMED || isCGNS ) // formats where group names must be unique { // check for equal group names within each mesh for( aMeshIter = aMeshList.begin(); aMeshIter != aMeshList.end(); aMeshIter++ ) { @@ -581,18 +562,6 @@ namespace format = "CGNS"; notSupportedElemTypes.push_back( SMESH::Entity_Ball ); } - else if ( isSAUV ) - { - format = "SAUV"; - notSupportedElemTypes.push_back( SMESH::Entity_Ball ); - notSupportedElemTypes.push_back( SMESH::Entity_BiQuad_Triangle ); - notSupportedElemTypes.push_back( SMESH::Entity_BiQuad_Quadrangle ); - notSupportedElemTypes.push_back( SMESH::Entity_TriQuad_Hexa ); - notSupportedElemTypes.push_back( SMESH::Entity_Hexagonal_Prism ); - notSupportedElemTypes.push_back( SMESH::Entity_Polygon ); - notSupportedElemTypes.push_back( SMESH::Entity_Quad_Polygon ); - notSupportedElemTypes.push_back( SMESH::Entity_Polyhedra ); - } else if ( isGMF ) { format = "GMF"; @@ -741,26 +710,19 @@ namespace } delete fd; } - else if ( isMED || isSAUV ) // Export to MED or SAUV + else if ( isMED ) // Export to MED { int defaultVersion = 0; QMap aFilterMap; - if ( isMED ) { - //filters << QObject::tr( "MED_FILES_FILTER" ) + " (*.med)"; - //QString vmed (aMesh->GetVersionString(-1, 2)); - SMESH::long_array_var mvok = aMesh->GetMEDVersionsCompatibleForAppend(); - if ( mvok->length() > 0) - defaultVersion = mvok[0]; // the current version to set the default filter on it - for ( CORBA::ULong i = 0; i < mvok->length(); ++i ) - { - QString vs = (char*)( SMESH_Comment( mvok[i]/10 ) << "." << mvok[i]%10 ); - aFilterMap.insert( QObject::tr( "MED_VX_FILES_FILTER" ).arg( vs ) + " (*.med)", mvok[i]); - } - } - else { // isSAUV - aFilterMap.insert("All files (*)", -1 ); - aFilterMap.insert("SAUV files (*.sauv)", defaultVersion ); // 0 = default filter (defaultVersion) - aFilterMap.insert("SAUV files (*.sauve)", -1 ); + //filters << QObject::tr( "MED_FILES_FILTER" ) + " (*.med)"; + //QString vmed (aMesh->GetVersionString(-1, 2)); + SMESH::long_array_var mvok = aMesh->GetMEDVersionsCompatibleForAppend(); + if ( mvok->length() > 0) + defaultVersion = mvok[0]; // the current version to set the default filter on it + for ( CORBA::ULong i = 0; i < mvok->length(); ++i ) + { + QString vs = (char*)( SMESH_Comment( mvok[i]/10 ) << "." << mvok[i]%10 ); + aFilterMap.insert( QObject::tr( "MED_VX_FILES_FILTER" ).arg( vs ) + " (*.med)", mvok[i]); } QStringList filters; QMap::const_iterator it = aFilterMap.begin(); @@ -946,15 +908,6 @@ namespace fields, geoAssFields.toLatin1().data(), zTol, saveNumbers ); } } - else if ( isSAUV ) - { - for( aMeshIter = aMeshList.begin(); aMeshIter != aMeshList.end(); aMeshIter++ ) - { - SMESH::SMESH_Mesh_var aMeshItem = SMESH::SMESH_Mesh::_narrow( (*aMeshIter).first ); - if( !aMeshItem->_is_nil() ) - aMeshItem->ExportSAUV( aFilename.toUtf8().data(), toCreateGroups ); - } - } else if ( isDAT ) { if ( aMeshOrGroup->_is_equivalent( aMesh )) @@ -2129,7 +2082,20 @@ void SMESHGUI::OnEditDelete() SMESH::RemoveHypothesisOrAlgorithmOnMesh(IObject); aStudyBuilder->RemoveObjectWithChildren( SO ); } - else {// default action: remove SObject from the study + else {// default action: remove SObject from the study + // Find Sub-Meshes and Group and delete corresopning visual objects and actors + _PTR(ChildIterator) it1 = aStudy->NewChildIterator(SO); + for (it1->InitEx(false); it1->More(); it1->Next()) { + _PTR(SObject) SObj = it1->Value(); + if (!SObj) continue; + if (SObj->FindAttribute(anAttr, "AttributeIOR")) { + SMESH::SMESH_GroupBase_var aGroup = SMESH::SMESH_GroupBase::_narrow(SMESH::SObjectToObject(SObj)); + SMESH::SMESH_subMesh_var aSubMesh = SMESH::SMESH_subMesh::_narrow(SMESH::SObjectToObject(SObj)); + if (!aGroup->_is_nil() || !aSubMesh->_is_nil()) { + SMESH::RemoveVisualObjectWithActors(SObj->GetID().c_str(), true); + } + } + } // san - it's no use opening a transaction here until UNDO/REDO is provided in SMESH //SUIT_Operation *op = new SALOMEGUI_ImportOperation(myActiveStudy); //op->start(); @@ -2599,14 +2565,12 @@ bool SMESHGUI::OnGUIEvent( int theCommandID ) case SMESHOp::OpImportMED: case SMESHOp::OpImportSTL: case SMESHOp::OpImportCGNS: - case SMESHOp::OpImportSAUV: case SMESHOp::OpImportGMF: case SMESHOp::OpPopupImportDAT: case SMESHOp::OpPopupImportUNV: case SMESHOp::OpPopupImportMED: case SMESHOp::OpPopupImportSTL: case SMESHOp::OpPopupImportCGNS: - case SMESHOp::OpPopupImportSAUV: case SMESHOp::OpPopupImportGMF: { if(isStudyLocked()) break; @@ -2637,14 +2601,12 @@ bool SMESHGUI::OnGUIEvent( int theCommandID ) case SMESHOp::OpExportUNV: case SMESHOp::OpExportSTL: case SMESHOp::OpExportCGNS: - case SMESHOp::OpExportSAUV: case SMESHOp::OpExportGMF: case SMESHOp::OpPopupExportDAT: case SMESHOp::OpPopupExportMED: case SMESHOp::OpPopupExportUNV: case SMESHOp::OpPopupExportSTL: case SMESHOp::OpPopupExportCGNS: - case SMESHOp::OpPopupExportSAUV: case SMESHOp::OpPopupExportGMF: { ::ExportMeshToFile(theCommandID); @@ -4114,7 +4076,6 @@ void SMESHGUI::initialize( CAM_Application* app ) #ifdef WITH_CGNS createSMESHAction( SMESHOp::OpImportCGNS, "IMPORT_CGNS" ); #endif - createSMESHAction( SMESHOp::OpImportSAUV, "IMPORT_SAUV" ); createSMESHAction( SMESHOp::OpImportGMF, "IMPORT_GMF" ); createSMESHAction( SMESHOp::OpPopupImportUNV, "IMPORT_UNV"); createSMESHAction( SMESHOp::OpPopupImportMED, "IMPORT_MED"); @@ -4122,7 +4083,6 @@ void SMESHGUI::initialize( CAM_Application* app ) #ifdef WITH_CGNS createSMESHAction( SMESHOp::OpPopupImportCGNS, "IMPORT_CGNS" ); #endif - createSMESHAction( SMESHOp::OpPopupImportSAUV, "IMPORT_SAUV" ); createSMESHAction( SMESHOp::OpPopupImportGMF, "IMPORT_GMF" ); createSMESHAction( SMESHOp::OpExportDAT, "DAT" ); @@ -4132,7 +4092,6 @@ void SMESHGUI::initialize( CAM_Application* app ) #ifdef WITH_CGNS createSMESHAction( SMESHOp::OpExportCGNS, "CGNS"); #endif - createSMESHAction( SMESHOp::OpExportSAUV, "SAUV"); createSMESHAction( SMESHOp::OpExportGMF, "GMF" ); createSMESHAction( SMESHOp::OpPopupExportDAT, "DAT" ); createSMESHAction( SMESHOp::OpPopupExportMED, "MED" ); @@ -4141,7 +4100,6 @@ void SMESHGUI::initialize( CAM_Application* app ) #ifdef WITH_CGNS createSMESHAction( SMESHOp::OpPopupExportCGNS, "CGNS"); #endif - createSMESHAction( SMESHOp::OpPopupExportSAUV, "SAUV"); createSMESHAction( SMESHOp::OpPopupExportGMF, "GMF" ); createSMESHAction( SMESHOp::OpFileInformation, "FILE_INFO" ); createSMESHAction( SMESHOp::OpDelete, "DELETE", "ICON_DELETE", Qt::Key_Delete ); @@ -4380,7 +4338,6 @@ void SMESHGUI::initialize( CAM_Application* app ) #ifdef WITH_CGNS createMenu( SMESHOp::OpImportCGNS, importId, -1 ); #endif - createMenu( SMESHOp::OpImportSAUV, importId, -1 ); createMenu( SMESHOp::OpImportGMF, importId, -1 ); createMenu( SMESHOp::OpExportDAT, exportId, -1 ); createMenu( SMESHOp::OpExportMED, exportId, -1 ); @@ -4389,7 +4346,6 @@ void SMESHGUI::initialize( CAM_Application* app ) #ifdef WITH_CGNS createMenu( SMESHOp::OpExportCGNS, exportId, -1 ); #endif - createMenu( SMESHOp::OpExportSAUV, exportId, -1 ); createMenu( SMESHOp::OpExportGMF, exportId, -1 ); createMenu( separator(), fileId, 10 ); @@ -4782,7 +4738,6 @@ void SMESHGUI::initialize( CAM_Application* app ) #ifdef WITH_CGNS createPopupItem( SMESHOp::OpPopupExportCGNS, OB, mesh_group, multiple_non_empty, anId ); #endif - createPopupItem( SMESHOp::OpPopupExportSAUV, OB, mesh_group, only_one_non_empty, anId ); createPopupItem( SMESHOp::OpPopupExportGMF, OB, mesh_group, only_one_non_empty, anId ); createPopupItem( SMESHOp::OpPopupExportDAT, OB, mesh_group, only_one_non_empty, anId ); @@ -4793,7 +4748,6 @@ void SMESHGUI::initialize( CAM_Application* app ) #ifdef WITH_CGNS createPopupItem( SMESHOp::OpPopupImportCGNS, OB, smesh, "", anId ); #endif - createPopupItem( SMESHOp::OpPopupImportSAUV, OB, smesh, "", anId ); createPopupItem( SMESHOp::OpPopupImportGMF, OB, smesh, "", anId ); createPopupItem( SMESHOp::OpPopupImportDAT, OB, smesh, "", anId ); popupMgr()->insert( separator(), -1, 0 ); @@ -5201,7 +5155,6 @@ bool SMESHGUI::activateModule( SUIT_Study* study ) << wrap("MED", "li") << wrap("STL", "li") << wrap("CGNS", "li") - << wrap("SAUV", "li") << wrap("GMF", "li"); lab = tr("INFO_AVAILABLE_FORMATS") + ":" + wrap(items.join(""), "ul"); items.clear(); diff --git a/src/SMESHGUI/SMESHGUI_HypothesesUtils.cxx b/src/SMESHGUI/SMESHGUI_HypothesesUtils.cxx index 3e5bd4122..7fee3a55b 100644 --- a/src/SMESHGUI/SMESHGUI_HypothesesUtils.cxx +++ b/src/SMESHGUI/SMESHGUI_HypothesesUtils.cxx @@ -34,7 +34,8 @@ #include "SMESHGUI_VTKUtils.h" #include "SMESHGUI_XmlHandler.h" -#include "SMESH_Actor.h" +#include +#include // SALOME GUI includes #include @@ -628,10 +629,13 @@ namespace SMESH HypothesisData* aHypData = GetHypothesisData(aHypType); QString aServLib = aHypData->ServerLibName; + SMESH_TRY; return SMESHGUI::GetSMESHGen()->IsApplicable( aHypType.toLatin1().data(), aServLib.toUtf8().data(), theGeomObject, toCheckAll); + SMESH_CATCH( SMESH::printErrorInDebugMode ); + return false; } diff --git a/src/SMESHGUI/SMESHGUI_Operations.h b/src/SMESHGUI/SMESHGUI_Operations.h index d1884f948..e24bcd558 100644 --- a/src/SMESHGUI/SMESHGUI_Operations.h +++ b/src/SMESHGUI/SMESHGUI_Operations.h @@ -40,14 +40,12 @@ namespace SMESHOp { OpImportMED = 1102, // MENU FILE - IMPORT - MED FILE OpImportSTL = 1103, // MENU FILE - IMPORT - STL FILE OpImportCGNS = 1104, // MENU FILE - IMPORT - CGNS FILE - OpImportSAUV = 1105, // MENU FILE - IMPORT - SAUV FILE OpImportGMF = 1106, // MENU FILE - IMPORT - GMF FILE OpPopupImportDAT = 1120, // POPUP MENU - IMPORT - DAT FILE OpPopupImportUNV = 1121, // POPUP MENU - IMPORT - UNV FILE OpPopupImportMED = 1122, // POPUP MENU - IMPORT - MED FILE OpPopupImportSTL = 1123, // POPUP MENU - IMPORT - STL FILE OpPopupImportCGNS = 1124, // POPUP MENU - IMPORT - CGNS FILE - OpPopupImportSAUV = 1125, // POPUP MENU - IMPORT - SAUV FILE OpPopupImportGMF = 1126, // POPUP MENU - IMPORT - GMF FILE // Export -------------------------//-------------------------------- OpExportDAT = 1200, // MENU FILE - EXPORT - DAT FILE @@ -55,14 +53,12 @@ namespace SMESHOp { OpExportUNV = 1202, // MENU FILE - EXPORT - UNV FILE OpExportSTL = 1203, // MENU FILE - EXPORT - STL FILE OpExportCGNS = 1204, // MENU FILE - EXPORT - CGNS FILE - OpExportSAUV = 1205, // MENU FILE - EXPORT - SAUV FILE OpExportGMF = 1206, // MENU FILE - EXPORT - GMF FILE OpPopupExportDAT = 1210, // POPUP MENU - EXPORT - DAT FILE OpPopupExportMED = 1211, // POPUP MENU - EXPORT - MED FILE OpPopupExportUNV = 1212, // POPUP MENU - EXPORT - UNV FILE OpPopupExportSTL = 1213, // POPUP MENU - EXPORT - STL FILE OpPopupExportCGNS = 1214, // POPUP MENU - EXPORT - CGNS FILE - OpPopupExportSAUV = 1215, // POPUP MENU - EXPORT - SAUV FILE OpPopupExportGMF = 1216, // POPUP MENU - EXPORT - GMF FILE // Mesh ---------------------------//-------------------------------- OpCreateMesh = 2030, // MENU MESH - CREATE MESH diff --git a/src/SMESHGUI/SMESHGUI_ReorientFacesDlg.cxx b/src/SMESHGUI/SMESHGUI_ReorientFacesDlg.cxx index d7b0b4f88..e5c74545a 100644 --- a/src/SMESHGUI/SMESHGUI_ReorientFacesDlg.cxx +++ b/src/SMESHGUI/SMESHGUI_ReorientFacesDlg.cxx @@ -81,8 +81,6 @@ #include // IDL includes -#include -#include CORBA_SERVER_HEADER(SMESH_Mesh) #include CORBA_SERVER_HEADER(SMESH_MeshEditor) // std @@ -91,8 +89,8 @@ #define SPACING 6 #define MARGIN 11 -enum { CONSTRUCTOR_POINT=0, CONSTRUCTOR_FACE, CONSTRUCTOR_VOLUME, - EObject, EPoint, EFace, EDirection, EVolumes }; +enum { CONSTRUCTOR_POINT=0, CONSTRUCTOR_FACE, CONSTRUCTOR_FACE_GROUPS, CONSTRUCTOR_VOLUME, + EObject, EPoint, EFace, EDirection, ERefGroups }; //======================================================================= /*! @@ -130,6 +128,7 @@ QWidget* SMESHGUI_ReorientFacesDlg::createMainFrame (QWidget* theParent) QPixmap iconReoriPoint (resMgr()->loadPixmap("SMESH", tr("ICON_DLG_REORIENT2D_POINT"))); QPixmap iconReoriFace (resMgr()->loadPixmap("SMESH", tr("ICON_DLG_REORIENT2D_FACE"))); + QPixmap iconReoriGroups(resMgr()->loadPixmap("SMESH", tr("ICON_DLG_REORIENT2D_GROUPS"))); QPixmap iconReoriVolum (resMgr()->loadPixmap("SMESH", tr("ICON_DLG_REORIENT2D_VOLUME"))); QGroupBox* aConstructorBox = new QGroupBox(tr("REORIENT_FACES"), aFrame); @@ -149,6 +148,11 @@ QWidget* SMESHGUI_ReorientFacesDlg::createMainFrame (QWidget* theParent) aConstructorGrpLayout->addWidget(aFaceBut); myConstructorGrp->addButton(aFaceBut, CONSTRUCTOR_FACE); + QRadioButton* aGroupBut= new QRadioButton(aConstructorBox); + aGroupBut->setIcon(iconReoriGroups); + aConstructorGrpLayout->addWidget(aGroupBut); + myConstructorGrp->addButton(aGroupBut, CONSTRUCTOR_FACE_GROUPS); + QRadioButton* aVolBut= new QRadioButton(aConstructorBox); aVolBut->setIcon(iconReoriVolum); aConstructorGrpLayout->addWidget(aVolBut); @@ -162,9 +166,10 @@ QWidget* SMESHGUI_ReorientFacesDlg::createMainFrame (QWidget* theParent) createObject( tr("POINT") , aFrame, EPoint ); createObject( tr("FACE") , aFrame, EFace ); createObject( tr("DIRECTION"), aFrame, EDirection ); - createObject( tr("VOLUMES"), aFrame, EVolumes ); - setNameIndication( EObject, OneName ); + createObject( tr("VOLUMES"), aFrame, ERefGroups ); + setNameIndication( EObject, ListOfNames ); setNameIndication( EFace, OneName ); + setNameIndication( ERefGroups, ListOfNames ); setReadOnly( EFace, false ); if ( QLineEdit* le = qobject_cast( objectWg( EFace, Control ) )) le->setValidator( new SMESHGUI_IdValidator( this,1 )); @@ -174,7 +179,6 @@ QWidget* SMESHGUI_ReorientFacesDlg::createMainFrame (QWidget* theParent) objectWg( EObject , Label )->setFixedWidth( width ); objectWg( EPoint , Label )->setFixedWidth( width ); objectWg( EFace , Label )->setFixedWidth( width ); - objectWg( EVolumes , Label )->setFixedWidth( width ); myOutsideChk = new QCheckBox( tr("OUTSIDE_VOLUME_NORMAL"), aFrame); myOutsideChk->setChecked( true ); @@ -246,14 +250,14 @@ QWidget* SMESHGUI_ReorientFacesDlg::createMainFrame (QWidget* theParent) aFaceGrpLayout->addWidget( objectWg( EFace, Btn ) ); aFaceGrpLayout->addWidget( objectWg( EFace, Control ) ); - myVolumFrm = new QFrame(aFrame); - QGridLayout* aVolumGrpLayout = new QGridLayout(myVolumFrm); - aVolumGrpLayout->setMargin(0); - aVolumGrpLayout->setSpacing(SPACING); - aVolumGrpLayout->addWidget( objectWg( EVolumes, Label ), 0, 0 ); - aVolumGrpLayout->addWidget( objectWg( EVolumes, Btn ), 0, 1 ); - aVolumGrpLayout->addWidget( objectWg( EVolumes, Control ), 0, 2 ); - aVolumGrpLayout->addWidget( myOutsideChk, 1, 0, 1, 3 ); + myRefGroupFrm = new QFrame(aFrame); + QGridLayout* aRefGrpLayout = new QGridLayout(myRefGroupFrm); + aRefGrpLayout->setMargin(0); + aRefGrpLayout->setSpacing(SPACING); + aRefGrpLayout->addWidget( objectWg( ERefGroups, Label ), 0, 0 ); + aRefGrpLayout->addWidget( objectWg( ERefGroups, Btn ), 0, 1 ); + aRefGrpLayout->addWidget( objectWg( ERefGroups, Control ), 0, 2 ); + aRefGrpLayout->addWidget( myOutsideChk, 1, 0, 1, 3 ); myDirFrm = new QFrame(aFrame); QHBoxLayout* aDirectGrpLayout = new QHBoxLayout(myDirFrm); @@ -273,7 +277,7 @@ QWidget* SMESHGUI_ReorientFacesDlg::createMainFrame (QWidget* theParent) QVBoxLayout* anOrientGrpLayout = new QVBoxLayout ( anOrientGrp ); anOrientGrpLayout->addWidget(myPointFrm); anOrientGrpLayout->addWidget(myFaceFrm); - anOrientGrpLayout->addWidget(myVolumFrm); + anOrientGrpLayout->addWidget(myRefGroupFrm); anOrientGrpLayout->addWidget(myDirFrm); @@ -298,7 +302,7 @@ void SMESHGUI_ReorientFacesDlg::constructorChange(int id) if ( id == CONSTRUCTOR_FACE ) { myPointFrm->hide(); - myVolumFrm->hide(); + myRefGroupFrm->hide(); myFaceFrm->show(); myDirFrm->show(); activateObject( EFace ); @@ -306,25 +310,57 @@ void SMESHGUI_ReorientFacesDlg::constructorChange(int id) else if ( id == CONSTRUCTOR_POINT ) { myFaceFrm->hide(); - myVolumFrm->hide(); + myRefGroupFrm->hide(); myPointFrm->show(); myDirFrm->show(); activateObject( EPoint ); } - else // CONSTRUCTOR_VOLUME + else // CONSTRUCTOR_VOLUME || CONSTRUCTOR_FACE_GROUPS { myFaceFrm->hide(); myPointFrm->hide(); myDirFrm->hide(); - myVolumFrm->show(); - activateObject( EVolumes ); + myOutsideChk->setVisible( id == CONSTRUCTOR_VOLUME ); + myRefGroupFrm->show(); + QAbstractButton* refButton = qobject_cast( objectWg( ERefGroups, Btn )); + refButton->setChecked( false ); // force ERefGroups activation + activateObject( ERefGroups ); + setLabel( ERefGroups, id == CONSTRUCTOR_VOLUME ? "VOLUMES" : "REF_GROUPS" ); + } + + // minimize width of labels + QFontMetrics font = objectWg( EDirection, Label )->fontMetrics(); + int width = 0; + for ( int obj = EObject; obj <= ERefGroups; ++obj ) + { + QLabel* label = qobject_cast< QLabel* >( objectWg( obj, Label )); + if ( label->isVisible() ) + width = std::max( width, font.width( label->text() )); + } + + for ( int obj = EObject; obj <= ERefGroups; ++obj ) + { + QWidget* label = objectWg( obj, Label ); + if ( label->isVisible() ) + label->setFixedWidth( width ); } } +//================================================================================ +/*! + * \brief Set object label + */ +//================================================================================ + +void SMESHGUI_ReorientFacesDlg::setLabel( int object, const char* text ) +{ + qobject_cast< QLabel* >( objectWg( object, Label ))->setText( tr( text )); +} + //================================================================================ /*! * \brief Constructor -*/ + */ //================================================================================ SMESHGUI_ReorientFacesOp::SMESHGUI_ReorientFacesOp() @@ -336,16 +372,16 @@ SMESHGUI_ReorientFacesOp::SMESHGUI_ReorientFacesOp() myDlg = new SMESHGUI_ReorientFacesDlg; myDlg->constructorChange( CONSTRUCTOR_POINT ); + myRefGroupFilter = new SMESH_TypeFilter( SMESH::GROUP_VOLUME ); + myRefSubMeshFilter = new SMESH_TypeFilter( SMESH::SUBMESH_SOLID ); + myRefMeshFilter = new SMESH_TypeFilter( SMESH::MESH ); + + myObjects = new SMESH::ListOfIDSources(); + myRefGroups = new SMESH::ListOfIDSources(); + // connect signals and slots connect( myDlg->objectWg( EFace, LightApp_Dialog::Control ), SIGNAL(textChanged(const QString&)), this, SLOT(onTextChange(const QString&))); - // connect(myDlg->myX, SIGNAL (valueChanged(double)), this, SLOT(redisplayPreview())); - // connect(myDlg->myY, SIGNAL (valueChanged(double)), this, SLOT(redisplayPreview())); - // connect(myDlg->myZ, SIGNAL (valueChanged(double)), this, SLOT(redisplayPreview())); - // connect(myDlg->myDX, SIGNAL (valueChanged(double)), this, SLOT(redisplayPreview())); - // connect(myDlg->myDY, SIGNAL (valueChanged(double)), this, SLOT(redisplayPreview())); - // connect(myDlg->myDZ, SIGNAL (valueChanged(double)), this, SLOT(redisplayPreview())); - } //======================================================================= @@ -357,23 +393,14 @@ void SMESHGUI_ReorientFacesOp::startOperation() { myObjectActor = 0; - // init simulation with a current View - //if ( myVectorPreview ) delete myVectorPreview; - // myVectorPreview = new SMESHGUI_MeshEditPreview(SMESH::GetViewWindow( getSMESHGUI() )); - // vtkProperty* aProp = vtkProperty::New(); - // aProp->SetRepresentationToWireframe(); - // aProp->SetColor(250, 0, 250); - // aProp->SetPointSize(5); - // aProp->SetLineWidth( SMESH::GetFloat("SMESH:element_width",1) + 1); - // myVectorPreview->GetActor()->SetProperty(aProp); - // aProp->Delete(); - SMESHGUI_SelectionOp::startOperation(); myDlg->show(); - mySelectionMode = 0; + mySelectionMode = EObject; myDlg->activateObject( EObject ); + + selectionDone(); } //================================================================================ @@ -384,8 +411,8 @@ void SMESHGUI_ReorientFacesOp::startOperation() void SMESHGUI_ReorientFacesOp::stopOperation() { - //myVectorPreview->SetVisibility(false); - if ( myObjectActor ) { + if ( myObjectActor ) + { myObjectActor->SetPointRepresentation(false); SMESH::RepaintCurrentView(); myObjectActor = 0; @@ -403,31 +430,43 @@ void SMESHGUI_ReorientFacesOp::stopOperation() void SMESHGUI_ReorientFacesOp::onActivateObject( int what ) { if ( what == mySelectionMode ) - return; - mySelectionMode = what; - switch ( mySelectionMode ) { - case EPoint: - case EDirection: - SMESH::SetPointRepresentation(true); - setSelectionMode( NodeSelection ); - SMESH::SetPickable(); - break; - case EObject: - case EVolumes: - SMESH::SetPointRepresentation(false); - setSelectionMode( ActorSelection ); - break; - case EFace: - SMESH::SetPointRepresentation(false); - setSelectionMode( FaceSelection ); - if ( myObjectActor ) - SMESH::SetPickable( myObjectActor ); - else + if ( what == ERefGroups ) + setRefFiltersByConstructor(); + } + else + { + mySelectionMode = what; + switch ( mySelectionMode ) + { + case EPoint: + case EDirection: + SMESH::SetPointRepresentation(true); + setSelectionMode( NodeSelection ); SMESH::SetPickable(); - break; + break; + case EObject: + SMESH::SetPointRepresentation(false); + setSelectionMode( ActorSelection ); + break; + case ERefGroups: + SMESH::SetPointRepresentation(false); + setSelectionMode( ActorSelection ); + setRefFiltersByConstructor(); + break; + case EFace: + SMESH::SetPointRepresentation(false); + setSelectionMode( FaceSelection ); + if ( myObjectActor ) + SMESH::SetPickable( myObjectActor ); + else + SMESH::SetPickable(); + break; + } } SMESHGUI_SelectionOp::onActivateObject( what ); + + myDlg->setLabel( EObject, onlyOneObjAllowed() ? "OBJECT" : "OBJECTS" ); } //================================================================================ @@ -448,12 +487,10 @@ SUIT_SelectionFilter* SMESHGUI_ReorientFacesOp::createFilter( const int what ) c filters.append( new SMESH_TypeFilter( SMESH::GROUP_FACE )); return new SMESH_LogicalFilter( filters, SMESH_LogicalFilter::LO_OR ); } - case EVolumes: + case ERefGroups: { QList filters; - filters.append( new SMESH_TypeFilter( SMESH::MESH )); - filters.append( new SMESH_TypeFilter( SMESH::SUBMESH_SOLID )); - filters.append( new SMESH_TypeFilter( SMESH::GROUP_VOLUME )); + filters << myRefGroupFilter << myRefSubMeshFilter << myRefMeshFilter; return new SMESH_LogicalFilter( filters, SMESH_LogicalFilter::LO_OR ); } case EPoint: @@ -472,6 +509,28 @@ SUIT_SelectionFilter* SMESHGUI_ReorientFacesOp::createFilter( const int what ) c return NULL; } +//================================================================================ +/*! + * \brief Switch between selection of faces and volumes according to the constructor + */ +//================================================================================ + +void SMESHGUI_ReorientFacesOp::setRefFiltersByConstructor() +{ + if ( constructorID() == CONSTRUCTOR_VOLUME ) + { + myRefMeshFilter ->setType( SMESH::MESH );// SMESH::NB_SMESH_TYPES + myRefGroupFilter ->setType( SMESH::GROUP_VOLUME ); + myRefSubMeshFilter->setType( SMESH::SUBMESH_SOLID ); + } + else + { + myRefMeshFilter ->setType( SMESH::NB_SMESH_TYPES ); // mesh not allowed + myRefGroupFilter ->setType( SMESH::GROUP_FACE ); + myRefSubMeshFilter->setType( SMESH::SUBMESH_FACE ); + } +} + //================================================================================ /*! * \brief get data from selection @@ -483,12 +542,6 @@ void SMESHGUI_ReorientFacesOp::selectionDone() if ( !myDlg->isVisible() || !myDlg->isEnabled() ) return; - if ( mySelectionMode == EVolumes ) - { - SMESHGUI_SelectionOp::selectionDone(); - return; - } - myDlg->clearSelection( mySelectionMode ); SALOME_ListIO aList; @@ -497,6 +550,15 @@ void SMESHGUI_ReorientFacesOp::selectionDone() if ( nbSelected == 0 ) return; + if ( onlyOneObjAllowed() && nbSelected != 1 ) + return; + + if ( mySelectionMode == ERefGroups ) + { + SMESHGUI_SelectionOp::selectionDone(); + return; + } + Handle(SALOME_InteractiveObject) anIO = aList.First(); try @@ -505,35 +567,27 @@ void SMESHGUI_ReorientFacesOp::selectionDone() { case EObject: { // get an actor of object - if ( nbSelected == 1 ) - { - myDlg->selectObject( EObject, anIO->getName(), 0, anIO->getEntry(), true ); - // typeById( aList.First()->getEntry(), - // SMESHGUI_SelectionOp::Object ), - myObjectActor = SMESH::FindActorByEntry( anIO->getEntry() ); - } + SMESHGUI_SelectionOp::selectionDone(); + myObjectActor = SMESH::FindActorByEntry( anIO->getEntry() ); break; } case EFace: { // get a face ID - if ( nbSelected == 1 ) + SVTK_TIndexedMapOfVtkId faceIndices; + selector()->GetIndex( anIO, faceIndices ); + if ( faceIndices.Extent() == 1 ) { - SVTK_TIndexedMapOfVtkId faceIndices; - selector()->GetIndex( anIO, faceIndices ); - if ( faceIndices.Extent() == 1 ) - { - SMESH_Actor* savedActor = myObjectActor; - myObjectActor = 0; // to prevent work of onTextChange() - myDlg->setObjectText( EFace, QString("%1").arg( faceIndices(1) )); - myObjectActor = savedActor; + SMESH_Actor* savedActor = myObjectActor; + myObjectActor = 0; // to prevent work of onTextChange() + myDlg->setObjectText( EFace, QString("%1").arg( faceIndices(1) )); + myObjectActor = savedActor; - if ( !myObjectActor ) - { - myDlg->selectObject( EObject, anIO->getName(), 0, anIO->getEntry(), true ); - // typeById( aList.First()->getEntry(), - // SMESHGUI_SelectionOp::Object ), - myObjectActor = SMESH::FindActorByEntry( anIO->getEntry() ); - } + if ( !myObjectActor ) + { + myDlg->selectObject( EObject, anIO->getName(), 0, anIO->getEntry(), true ); + // typeById( aList.First()->getEntry(), + // SMESHGUI_SelectionOp::Object ), + myObjectActor = SMESH::FindActorByEntry( anIO->getEntry() ); } } break; @@ -541,9 +595,6 @@ void SMESHGUI_ReorientFacesOp::selectionDone() case EPoint: case EDirection: { // set XYZ by selected nodes or vertices - if ( mySelectionMode == EPoint && aList.Extent() > 1 ) - return; - TColgp_SequenceOfXYZ points; for( SALOME_ListIteratorOfListIO anIt( aList ); anIt.More(); anIt.Next() ) { @@ -660,24 +711,30 @@ bool SMESHGUI_ReorientFacesOp::onApply() try { SUIT_OverrideCursor wc; - SMESH::SMESH_Mesh_var aMesh = myObject->GetMesh(); + SMESH::SMESH_Mesh_var aMesh = myObjects[0]->GetMesh(); if ( aMesh->_is_nil() ) return false; SMESH::SMESH_MeshEditor_var aMeshEditor = aMesh->GetMeshEditor(); if (aMeshEditor->_is_nil()) return false; int aResult = 0; - if ( myDlg->myConstructorGrp->checkedId() == CONSTRUCTOR_VOLUME ) + switch ( constructorID() ) + { + case CONSTRUCTOR_VOLUME: { - SMESH::ListOfIDSources_var faceGroups = new SMESH::ListOfIDSources; - faceGroups->length(1); - faceGroups[0] = myObject; - bool outsideNormal = myDlg->myOutsideChk->isChecked(); - aResult = aMeshEditor->Reorient2DBy3D( faceGroups, myVolumeObj, outsideNormal ); + aResult = aMeshEditor->Reorient2DBy3D( myObjects, myRefGroups[0], outsideNormal ); + + break; } - else + case CONSTRUCTOR_FACE_GROUPS: + { + aResult = aMeshEditor->Reorient2DByNeighbours( myObjects, myRefGroups ); + + break; + } + default: { SMESH::DirStruct direction; direction.PS.x = myDlg->myDX->GetValue(); @@ -685,7 +742,7 @@ bool SMESHGUI_ReorientFacesOp::onApply() direction.PS.z = myDlg->myDZ->GetValue(); long face = myDlg->objectText( EFace ).toInt(); - if ( myDlg->myConstructorGrp->checkedId() == CONSTRUCTOR_POINT ) + if ( constructorID() == CONSTRUCTOR_POINT ) face = -1; SMESH::PointStruct point; @@ -695,7 +752,8 @@ bool SMESHGUI_ReorientFacesOp::onApply() aMesh->SetParameters( aParameters.join(":").toUtf8().constData() ); - aResult = aMeshEditor->Reorient2D( myObject, direction, face, point ); + aResult = aMeshEditor->Reorient2D( myObjects[0], direction, face, point ); + } } if (aResult) @@ -726,47 +784,71 @@ bool SMESHGUI_ReorientFacesOp::onApply() bool SMESHGUI_ReorientFacesOp::isValid( QString& msg ) { - // check object - QString objectEntry = myDlg->selectedObject( EObject ); - _PTR(SObject) pSObject = SMESH::getStudy()->FindObjectID( objectEntry.toUtf8().data() ); - myObject = SMESH::SMESH_IDSource::_narrow( _CAST( SObject,pSObject )->GetObject() ); - if ( myObject->_is_nil() ) + // Check objects + + QStringList objectEntries; + myDlg->selectedObject( EObject, objectEntries ); + if ( objectEntries.size() == 0 ) { msg = tr("NO_OBJECT_SELECTED"); return false; } - bool hasFaces = false; - SMESH::array_of_ElementType_var types = myObject->GetTypes(); - for ( size_t i = 0; i < types->length() && !hasFaces; ++i ) - hasFaces = ( types[i] == SMESH::FACE ); - if ( !hasFaces ) + myObjects->length( objectEntries.size() ); + int nbObj = 0; + for ( QString & entry : objectEntries ) + { + SMESH::SMESH_IDSource_var obj = SMESH::EntryToInterface< SMESH::SMESH_IDSource >( entry ); + if ( !obj->_is_nil() ) + { + bool hasFaces = false; + SMESH::array_of_ElementType_var types = obj->GetTypes(); + for ( size_t i = 0; i < types->length() && !hasFaces; ++i ) + hasFaces = ( types[i] == SMESH::FACE ); + if ( hasFaces ) + myObjects[ nbObj++ ] = SMESH::SMESH_IDSource::_duplicate( obj ); + } + } + if ( nbObj == 0 ) { msg = tr("NO_FACES"); return false; } + myObjects->length( nbObj ); - // check volume object - if ( myDlg->myConstructorGrp->checkedId() == CONSTRUCTOR_VOLUME ) + // Check volume object or ref faces + + int constructorType = constructorID(); + if ( constructorType >= CONSTRUCTOR_FACE_GROUPS ) { - objectEntry = myDlg->selectedObject( EVolumes ); - _PTR(SObject) pSObject = SMESH::getStudy()->FindObjectID( objectEntry.toUtf8().data() ); - myVolumeObj = SMESH::SObjectToInterface< SMESH::SMESH_IDSource>( pSObject ); - if ( myVolumeObj->_is_nil() ) + objectEntries.clear(); + myDlg->selectedObject( ERefGroups, objectEntries ); + myRefGroups->length( objectEntries.size() ); + nbObj = 0; + for ( QString & entry : objectEntries ) { - msg = tr("NO_VOLUME_OBJECT_SELECTED"); - return false; + SMESH::SMESH_IDSource_var obj = SMESH::EntryToInterface< SMESH::SMESH_IDSource >( entry ); + if ( !obj->_is_nil() ) + { + bool hasElems = false; + SMESH::ElementType elemType = + ( constructorType == CONSTRUCTOR_VOLUME ? SMESH::VOLUME : SMESH::FACE ); + SMESH::array_of_ElementType_var types = obj->GetTypes(); + for ( size_t i = 0; i < types->length() && !hasElems; ++i ) + hasElems = ( types[i] == elemType ); + if ( hasElems ) + myRefGroups[ nbObj++ ] = SMESH::SMESH_IDSource::_duplicate( obj ); + } } - bool hasVolumes = false; - types = myVolumeObj->GetTypes(); - for ( size_t i = 0; i < types->length() && !hasVolumes; ++i ) - hasVolumes = ( types[i] == SMESH::VOLUME ); - if ( !hasVolumes ) + if ( nbObj == 0 && constructorType == CONSTRUCTOR_VOLUME ) { msg = tr("NO_VOLUMES"); return false; } + myRefGroups->length( nbObj ); } - // check vector + + // Check vector + gp_Vec vec( myDlg->myDX->GetValue(), myDlg->myDY->GetValue(), myDlg->myDZ->GetValue() ); @@ -776,8 +858,9 @@ bool SMESHGUI_ReorientFacesOp::isValid( QString& msg ) return false; } - // check face ID - if ( myDlg->myConstructorGrp->checkedId() == CONSTRUCTOR_FACE ) + // Check face ID + + if ( constructorID() == CONSTRUCTOR_FACE ) { int faceID = myDlg->objectText( EFace ).toInt(); bool faceOK = ( faceID > 0 ); @@ -789,8 +872,8 @@ bool SMESHGUI_ReorientFacesOp::isValid( QString& msg ) } else { - SMESH::SMESH_Mesh_var aMesh = myObject->GetMesh(); - if ( !aMesh->_is_nil() ) + SMESH::SMESH_Mesh_var aMesh = myObjects[0]->GetMesh(); + if ( !aMesh->_is_nil() ) faceOK = ( aMesh->GetElementType( faceID, true ) == SMESH::FACE ); } } @@ -807,7 +890,7 @@ bool SMESHGUI_ReorientFacesOp::isValid( QString& msg ) //================================================================================ /*! * \brief Destructor -*/ + */ //================================================================================ SMESHGUI_ReorientFacesOp::~SMESHGUI_ReorientFacesOp() @@ -828,6 +911,29 @@ LightApp_Dialog* SMESHGUI_ReorientFacesOp::dlg() const return myDlg; } +//================================================================================ +/*! + * \brief ID of a current constructor: CONSTRUCTOR_FACE, CONSTRUCTOR_POINT etc. + */ +//================================================================================ + +int SMESHGUI_ReorientFacesOp::constructorID() +{ + return myDlg->myConstructorGrp->checkedId(); +} + +//================================================================================ +/*! + * \brief Check if selection of multiple objects allowed + */ +//================================================================================ + +bool SMESHGUI_ReorientFacesOp::onlyOneObjAllowed() +{ + return (( constructorID() <= CONSTRUCTOR_FACE ) || + ( constructorID() == CONSTRUCTOR_VOLUME && mySelectionMode == ERefGroups )); +} + //================================================================================ /*! * \brief update preview @@ -836,110 +942,4 @@ LightApp_Dialog* SMESHGUI_ReorientFacesOp::dlg() const void SMESHGUI_ReorientFacesOp::redisplayPreview() { -// SMESH::MeshPreviewStruct_var aMeshPreviewStruct; - -// bool moveShown = false; -// if ( myObjectActor) -// { -// const bool autoSearch = myDlg->myAutoSearchChkBox->isChecked(); -// const bool preview = myDlg->myPreviewChkBox->isChecked(); -// if ( autoSearch ) -// { -// myDlg->myCurrentX->SetValue(0); -// myDlg->myCurrentY->SetValue(0); -// myDlg->myCurrentZ->SetValue(0); -// myDlg->myDX->SetValue(0); -// myDlg->myDY->SetValue(0); -// myDlg->myDZ->SetValue(0); -// myDlg->myId->setText(""); -// } -// QString msg; -// if ( autoSearch || isValid( msg ) ) -// { -// try { -// SMESH::SMESH_Mesh_var aMesh = SMESH::GetMeshByIO(myObjectActor->getIO()); -// if (!aMesh->_is_nil()) { -// SMESH::SMESH_MeshEditor_var aPreviewer = aMesh->GetMeshEditPreviewer(); -// if (!aPreviewer->_is_nil()) -// { -// SUIT_OverrideCursor aWaitCursor; - -// int anId = 0; -// if ( autoSearch ) -// anId = aPreviewer->FindNodeClosestTo(myDlg->myX->GetValue(), -// myDlg->myY->GetValue(), -// myDlg->myZ->GetValue()); -// else -// anId = myDlg->myId->text().toInt(); - -// // find id and/or just compute preview -// aPreviewer->MoveNode(anId, -// myDlg->myX->GetValue(), -// myDlg->myY->GetValue(), -// myDlg->myZ->GetValue()); -// if ( autoSearch ) { // set found id -// QString idTxt("%1"); -// if ( anId > 0 ) -// idTxt = idTxt.arg( anId ); -// else -// idTxt = ""; -// myDlg->myId->setText( idTxt ); -// } - -// SMESH::double_array* aXYZ = aMesh->GetNodeXYZ( anId ); -// if( aXYZ && aXYZ->length() >= 3 ) -// { -// double x = aXYZ->operator[](0); -// double y = aXYZ->operator[](1); -// double z = aXYZ->operator[](2); -// double dx = myDlg->myX->GetValue() - x; -// double dy = myDlg->myY->GetValue() - y; -// double dz = myDlg->myZ->GetValue() - z; -// myDlg->myCurrentX->SetValue(x); -// myDlg->myCurrentY->SetValue(y); -// myDlg->myCurrentZ->SetValue(z); -// myDlg->myDX->SetValue(dx); -// myDlg->myDY->SetValue(dy); -// myDlg->myDZ->SetValue(dz); -// } - -// if ( preview ) { // fill preview data -// aMeshPreviewStruct = aPreviewer->GetPreviewData(); -// moveShown = ( anId > 0 ); -// } -// } -// } -// }catch (...) { -// } -// } -// } - -// if ( !moveShown ) -// { -// aMeshPreviewStruct = new SMESH::MeshPreviewStruct(); - -// aMeshPreviewStruct->nodesXYZ.length(1); -// aMeshPreviewStruct->nodesXYZ[0].x = myDlg->myX->GetValue(); -// aMeshPreviewStruct->nodesXYZ[0].y = myDlg->myY->GetValue(); -// aMeshPreviewStruct->nodesXYZ[0].z = myDlg->myZ->GetValue(); - -// aMeshPreviewStruct->elementTypes.length(1); -// aMeshPreviewStruct->elementTypes[0].SMDS_ElementType = SMESH::NODE; -// aMeshPreviewStruct->elementTypes[0].isPoly = false; -// aMeshPreviewStruct->elementTypes[0].nbNodesInElement = 1; - -// aMeshPreviewStruct->elementConnectivities.length(1); -// aMeshPreviewStruct->elementConnectivities[0] = 0; -// } - -// // display data -// if ( & aMeshPreviewStruct.in() ) -// { -// myVectorPreview->SetData(aMeshPreviewStruct.in()); -// } -// else -// { -// myVectorPreview->SetVisibility(false); -// } - } diff --git a/src/SMESHGUI/SMESHGUI_ReorientFacesDlg.h b/src/SMESHGUI/SMESHGUI_ReorientFacesDlg.h index e9df0563a..5b86db6ff 100644 --- a/src/SMESHGUI/SMESHGUI_ReorientFacesDlg.h +++ b/src/SMESHGUI/SMESHGUI_ReorientFacesDlg.h @@ -27,31 +27,37 @@ #define SMESHGUI_ReorientFacesDlg_H // SMESH includes + #include "SMESH_SMESHGUI.hxx" #include "SMESHGUI_Dialog.h" #include "SMESHGUI_SelectionOp.h" +#include +#include CORBA_SERVER_HEADER(SMESH_Mesh) + class QButtonGroup; class QCheckBox; class QLineEdit; class SMESHGUI_SpinBox; class SMESHGUI_ReorientFacesDlg; +class SMESH_TypeFilter; -/*! +/*! ================================================================================ * \brief Operation to reorient faces according to some criterion */ + class SMESHGUI_EXPORT SMESHGUI_ReorientFacesOp: public SMESHGUI_SelectionOp { Q_OBJECT -public: + public: SMESHGUI_ReorientFacesOp(); virtual ~SMESHGUI_ReorientFacesOp(); virtual LightApp_Dialog* dlg() const; -protected: + protected: virtual void startOperation(); virtual void stopOperation(); @@ -60,27 +66,35 @@ protected: virtual void selectionDone(); bool isValid( QString& ); + void setRefFiltersByConstructor(); + int constructorID(); -protected slots: + + protected slots: virtual bool onApply(); -private slots: + private slots: virtual void onActivateObject( int ); void redisplayPreview(); void onTextChange( const QString& ); + bool onlyOneObjAllowed(); -private: - SMESHGUI_ReorientFacesDlg* myDlg; + private: - //SMESHGUI_MeshEditPreview* myVectorPreview; - SMESH_Actor* myObjectActor; - int mySelectionMode; + SMESHGUI_ReorientFacesDlg* myDlg; - SMESH::SMESH_IDSource_var myObject; - SMESH::SMESH_IDSource_var myVolumeObj; + SMESH_Actor* myObjectActor; + int mySelectionMode; + + SMESH_TypeFilter* myRefGroupFilter; + SMESH_TypeFilter* myRefSubMeshFilter; + SMESH_TypeFilter* myRefMeshFilter; + + SMESH::ListOfIDSources_var myObjects; + SMESH::ListOfIDSources_var myRefGroups; }; -/*! +/*! ================================================================================ * \brief Dialog to reorient faces according to vector */ @@ -88,7 +102,7 @@ class SMESHGUI_EXPORT SMESHGUI_ReorientFacesDlg : public SMESHGUI_Dialog { Q_OBJECT -public: + public: SMESHGUI_ReorientFacesDlg(); public slots: @@ -96,12 +110,13 @@ public slots: private: QWidget* createMainFrame( QWidget* ); + void setLabel( int object, const char* text ); QButtonGroup* myConstructorGrp; QFrame* myFaceFrm; QFrame* myPointFrm; QFrame* myDirFrm; - QFrame* myVolumFrm; + QFrame* myRefGroupFrm; QCheckBox* myOutsideChk; SMESHGUI_SpinBox* myX; SMESHGUI_SpinBox* myY; diff --git a/src/SMESHGUI/SMESH_images.ts b/src/SMESHGUI/SMESH_images.ts index 317a769cb..74697d463 100644 --- a/src/SMESHGUI/SMESH_images.ts +++ b/src/SMESHGUI/SMESH_images.ts @@ -495,6 +495,10 @@ ICON_DLG_REORIENT2D_FACE reorient_faces_face.png + + ICON_DLG_REORIENT2D_GROUPS + reorient_faces_ref_groups.png + ICON_DLG_REORIENT2D_VOLUME reorient_faces_volume.png diff --git a/src/SMESHGUI/SMESH_msg_en.ts b/src/SMESHGUI/SMESH_msg_en.ts index 9c982d71e..67ca49fe5 100644 --- a/src/SMESHGUI/SMESH_msg_en.ts +++ b/src/SMESHGUI/SMESH_msg_en.ts @@ -11,10 +11,6 @@ MED_FILES_FILTER MED files - - SAUV_FILES_FILTER - SAUV files - IDEAS_FILES_FILTER IDEAS files @@ -648,10 +644,6 @@ MEN_EXPORT_GMF Export to GMF file - - MEN_EXPORT_SAUV - Export to SAUV file - MEN_EXPORT_STL Export to STL file @@ -876,14 +868,6 @@ MEN_GMF GMF file - - MEN_IMPORT_SAUV - SAUV file - - - MEN_SAUV - SAUV file - MEN_MERGE Merge Nodes @@ -3464,10 +3448,6 @@ Use Display Entity menu command to show them. STB_EXPORT_GMF Export to GMF file - - STB_EXPORT_SAUV - Export to SAUV file - STB_EXPORT_STL Export to STL file @@ -3600,14 +3580,6 @@ Use Display Entity menu command to show them. STB_GMF Export GMF file - - STB_IMPORT_SAUV - Import SAUV file - - - STB_SAUV - Export SAUV file - STB_MERGE Merge nodes @@ -4164,10 +4136,6 @@ Use Display Entity menu command to show them. TOP_EXPORT_MED Export to MED file - - TOP_EXPORT_SAUV - Export to SAUV file - TOP_EXPORT_STL Export to STL file @@ -4300,14 +4268,6 @@ Use Display Entity menu command to show them. TOP_GMF Export GMF file - - TOP_IMPORT_SAUV - Import SAUV file - - - TOP_SAUV - Export SAUV file - TOP_MERGE Merge nodes @@ -8649,6 +8609,10 @@ red in the Object Browser. OBJECT Object + + OBJECTS + Objects + POINT Point @@ -8669,6 +8633,10 @@ red in the Object Browser. VOLUMES Volumes + + REF_GROUPS + Ref. objects (optional) + OUTSIDE_VOLUME_NORMAL Face normal outside volume diff --git a/src/SMESHGUI/SMESH_msg_fr.ts b/src/SMESHGUI/SMESH_msg_fr.ts index 992eab2df..5ff731606 100644 --- a/src/SMESHGUI/SMESH_msg_fr.ts +++ b/src/SMESHGUI/SMESH_msg_fr.ts @@ -11,10 +11,6 @@ MED_FILES_FILTER Fichiers MED - - SAUV_FILES_FILTER - Fichiers SAUV - IDEAS_FILES_FILTER Fichiers IDEAS @@ -648,10 +644,6 @@ MEN_EXPORT_GMF Exporter au format GMF - - MEN_EXPORT_SAUV - Exporter au format SAUV (ASCII) - MEN_EXPORT_STL Exporter au format STL @@ -682,15 +674,15 @@ TOP_REORIENT_2D - Réorienter des faces selon un vecteur + Réorienter des faces MEN_REORIENT_2D - Réorienter des faces selon un vecteur + Réorienter des faces STB_REORIENT_2D - Réorienter des faces selon un vecteur + Réorienter des faces TOP_FIND_ELEM @@ -876,14 +868,6 @@ MEN_GMF Fichier GMF - - MEN_IMPORT_SAUV - Fichier SAUV (ASCII) - - - MEN_SAUV - Fichier SAUV (ASCII) - MEN_MERGE Fusionner les nœuds @@ -3451,10 +3435,6 @@ Utilisez le menu "Visualiser une entité" pour les afficher. STB_EXPORT_GMF Exporter au format GMF - - STB_EXPORT_SAUV - Exporter au format SAUV (ASCII) - STB_EXPORT_STL Exporter au format STL @@ -3587,14 +3567,6 @@ Utilisez le menu "Visualiser une entité" pour les afficher. STB_GMF Exporter un fichier GMF - - STB_IMPORT_SAUV - Importer un fichier SAUV (ASCII) - - - STB_SAUV - Exporter un fichier SAUV (ASCII) - STB_MERGE Fusionner les nœuds @@ -4151,10 +4123,6 @@ Utilisez le menu "Visualiser une entité" pour les afficher. TOP_EXPORT_MED Exporter au format MED - - TOP_EXPORT_SAUV - Exporter au format SAUV (ASCII) - TOP_EXPORT_STL Exporter au format STL @@ -4287,14 +4255,6 @@ Utilisez le menu "Visualiser une entité" pour les afficher. TOP_GMF Exporter un fichier GMF - - TOP_IMPORT_SAUV - Importer un fichier SAUV (ASCII) - - - TOP_SAUV - Exporter un fichier SAUV (ASCII) - TOP_MERGE Fusionner les nœuds @@ -4883,7 +4843,11 @@ Ouvrez une fenêtre VTK et essayez de nouveau PREF_SHOW_WARN - Affiche un avertissement quand un groupe est exporté + Afficher un avertissement quand un groupe est exporté + + + PREF_MED_SAVE_NUMS + Enregistrer les numéros des nœuds/mailles dans le fichier MED PREF_ZTOLERANCE @@ -8649,7 +8613,7 @@ en rouge dans le browser. SMESHGUI_ReorientFacesDlg CAPTION - Réorienter des faces selon un vector + Réorienter des faces REORIENT_FACES @@ -8663,6 +8627,10 @@ en rouge dans le browser. OBJECT Objet + + OBJECTS + Objets + POINT Point @@ -8683,6 +8651,10 @@ en rouge dans le browser. VOLUMES Volumes + + REF_GROUPS + Objets de référence (optionnel) + OUTSIDE_VOLUME_NORMAL Normale de face en dehors du volume diff --git a/src/SMESHGUI/SMESH_msg_ja.ts b/src/SMESHGUI/SMESH_msg_ja.ts index c1c0ae8c4..369b86a57 100644 --- a/src/SMESHGUI/SMESH_msg_ja.ts +++ b/src/SMESHGUI/SMESH_msg_ja.ts @@ -11,10 +11,6 @@ MED_FILES_FILTER MEDファイル - - SAUV_FILES_FILTER - SAUVファイル - IDEAS_FILES_FILTER IDEAS ファイル @@ -503,10 +499,6 @@ MEN_EXPORT_GMF GMF形式でエクスポート - - MEN_EXPORT_SAUV - SAUV (ASCII) 形式でエクスポート - MEN_EXPORT_STL STL形式でエクスポート @@ -727,14 +719,6 @@ MEN_GMF GMFファイル - - MEN_IMPORT_SAUV - SAUVファイル - - - MEN_SAUV - SAUVファイル - MEN_MERGE 節点の結合 @@ -3147,10 +3131,6 @@ STB_EXPORT_GMF 組み換えをエクスポートします。 - - STB_EXPORT_SAUV - SAUV (ASCII) 形式でエクスポート - STB_EXPORT_STL STL形式でエクスポート @@ -3279,14 +3259,6 @@ STB_GMF 組み換えファイルをエクスポートします。 - - STB_IMPORT_SAUV - バックアップ (ASCII) ファイルをインポートします。 - - - STB_SAUV - バックアップ (ASCII) ファイルをエクスポートします。 - STB_MERGE ノードを結合します。 @@ -3827,10 +3799,6 @@ TOP_EXPORT_MED MED形式でエクスポート - - TOP_EXPORT_SAUV - SAUV (ASCII) 形式でエクスポート - TOP_EXPORT_STL STL形式でエクスポート @@ -3959,14 +3927,6 @@ TOP_GMF 組み換えファイルをエクスポートします。 - - TOP_IMPORT_SAUV - バックアップ (ASCII) ファイルをインポートします。 - - - TOP_SAUV - バックアップ (ASCII) ファイルをエクスポートします。 - TOP_MERGE ノードを結合します。 diff --git a/src/SMESHUtils/CMakeLists.txt b/src/SMESHUtils/CMakeLists.txt index 8eb4e3b68..e35033177 100644 --- a/src/SMESHUtils/CMakeLists.txt +++ b/src/SMESHUtils/CMakeLists.txt @@ -62,6 +62,7 @@ SET(SMESHUtils_HEADERS SMESH_Delaunay.hxx SMESH_Indexer.hxx SMESH_BoostTxtArchive.hxx + SMESH_MGLicenseKeyGen.hxx ) # --- sources --- @@ -86,6 +87,7 @@ SET(SMESHUtils_SOURCES SMESH_Slot.cxx SMESH_PolyLine.cxx SMESH_BoostTxtArchive.cxx + SMESH_MGLicenseKeyGen.cxx ) # --- rules --- diff --git a/src/SMESHUtils/SMESH_BoostTxtArchive.hxx b/src/SMESHUtils/SMESH_BoostTxtArchive.hxx index cb5071f69..5806ffba4 100644 --- a/src/SMESHUtils/SMESH_BoostTxtArchive.hxx +++ b/src/SMESHUtils/SMESH_BoostTxtArchive.hxx @@ -39,7 +39,7 @@ namespace SMESHUtils * 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; + * Usage: ObjType obj; SMESHUtils::BoostTxtArchive( arcString ) >> obj; */ class SMESHUtils_EXPORT BoostTxtArchive { diff --git a/src/SMESHUtils/SMESH_MGLicenseKeyGen.cxx b/src/SMESHUtils/SMESH_MGLicenseKeyGen.cxx new file mode 100644 index 000000000..b058e86a2 --- /dev/null +++ b/src/SMESHUtils/SMESH_MGLicenseKeyGen.cxx @@ -0,0 +1,516 @@ +// Copyright (C) 2007-2021 CEA/DEN, EDF R&D, OPEN CASCADE +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// +// File : SMESHUtils_MGLicenseKeyGen.cxx +// Created : Sat Jul 31 18:54:16 2021 +// Author : Edward AGAPOV (OCC) + +#include "SMESH_MGLicenseKeyGen.hxx" + +#include "SMESH_Comment.hxx" +#include "SMESH_File.hxx" +#include "SMESH_TryCatch.hxx" + +#include +#include + +#include // getenv, system + +#include +#include +namespace boofs = boost::filesystem; + +#ifdef WIN32 + +# include +# include + +# define LibHandle HMODULE +# define LoadLib( name ) LoadLibrary( name ) +# define GetProc GetProcAddress +# define UnLoadLib( handle ) FreeLibrary( handle ); + +#else // WIN32 + +# include + +# define LibHandle void* +# define LoadLib( name ) dlopen( name, RTLD_LAZY | RTLD_LOCAL ) +# define GetProc dlsym +# define UnLoadLib( handle ) dlclose( handle ); + +#endif // WIN32 + +// to retrieve description of exception caught by SMESH_TRY +#undef SMESH_CAUGHT +#define SMESH_CAUGHT error = + + +namespace +{ + static LibHandle theLibraryHandle = nullptr; //!< handle of a loaded library + + const char* theEnvVar = "SALOME_MG_KEYGEN_LIB_PATH"; /* var specifies either full file name + of libSalomeMeshGemsKeyGenerator or + URL to download the library from */ + + const char* theTmpEnvVar = "SALOME_TMP_DIR"; // directory to download the library to + + //----------------------------------------------------------------------------------- + /*! + * \brief Remove library file at destruction in case if it was downloaded from server + */ + //----------------------------------------------------------------------------------- + + struct LibraryFile + { + std::string _name; // full file name + bool _isURL; + + LibraryFile(): _isURL( false ) {} + + ~LibraryFile() + { + if ( _isURL ) + { + if ( theLibraryHandle ) + { + UnLoadLib( theLibraryHandle ); + theLibraryHandle = nullptr; + } + + std::string tmpDir; // tmp dir that should not be removed + if ( const char* libPath = getenv( theTmpEnvVar )) + { + tmpDir = libPath; + while (( !tmpDir.empty() ) && + ( tmpDir.back() == '/' || tmpDir.back() == '\\' )) + tmpDir.pop_back(); + } + + while ( SMESH_File( _name ).remove() ) + { + size_t length = _name.size(); + _name = boofs::path( _name ).parent_path().string(); // goto parent directory + if ( _name.size() == length ) + break; // no more parents + + if ( _name == tmpDir ) + break; // don't remove tmp dir + + if ( !Kernel_Utils::IsEmptyDir( _name )) + break; + } + } + } + }; + + + //================================================================================ + /*! + * \brief Retrieve description of the last error + * \param [out] error - return the description + * \return bool - true if the description found + */ + //================================================================================ + + bool getLastError( std::string& error ) + { +#ifndef WIN32 + + if ( const char* text = dlerror() ) + { + error = text; + return true; + } + return false; + +#else + + DWORD dw = GetLastError(); + void* cstr; + DWORD msgLen = FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, + NULL, + dw, + MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language + (LPTSTR) &cstr, + 0, + NULL + ); + if ( msgLen > 0 ) { +# if defined( UNICODE ) + error = Kernel_Utils::encode_s((wchar_t*)cstr); +# else + error = (char*)cstr; +# endif + LocalFree(cstr); + } + + return (bool)msgLen; + +#endif + } + + //================================================================================ + /*! + * \brief Adjust file extension according to the platform + */ + //================================================================================ + + bool setExtension( std::string& fileName, std::string& error ) + { + if ( fileName.empty() ) + { + error = "Library file name is empty"; + return false; + } +#if defined(WIN32) + std::string ext = ".dll"; +#elif defined(__APPLE__) + std::string ext = ".dylib"; +#else + std::string ext = ".so"; +#endif + + fileName = fileName.substr( 0, fileName.find_last_of('.')) + ext; + return true; + } + + //================================================================================ + /*! + * \brief Check if library file name looks like an URL + * \param [in,out] libraryFile - holds file name and returns result in _isURL member field + * \return bool - true if the file name looks like an URL + */ + //================================================================================ + + bool isURL( LibraryFile & libraryFile ) + { + {// round1 + enum { SCHEME = 2, AUTHORITY = 4, PATH = 5 }; // sub-strings + boost::regex urlRegex ( R"(^(([^:\/?#]+):)?(//([^\/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?)", + boost::regex::extended ); + boost::smatch matchResult; + + libraryFile._isURL = false; + if ( boost::regex_match( libraryFile._name, matchResult, urlRegex )) + libraryFile._isURL = ( !matchResult.str( SCHEME ).empty() && + !matchResult.str( AUTHORITY ).empty() && + !matchResult.str( PATH ).empty() ); + } + if(libraryFile._isURL) + return true; + {// round2 + enum { HOST = 2, PORT = 3, PATH = 4 }; // sub-strings + boost::regex urlRegex ( R"(^(([^:\/?#]+):)?([^/]+)?(/[^#]*))", + boost::regex::extended ); + boost::smatch matchResult; + + libraryFile._isURL = false; + if ( boost::regex_match( libraryFile._name, matchResult, urlRegex )) + libraryFile._isURL = ( !matchResult.str( HOST ).empty() && + !matchResult.str( PORT ).empty() && + !matchResult.str( PATH ).empty() ); + } + return libraryFile._isURL; + } + + //================================================================================ + /*! + * \brief Download libraryFile._name URL to SALOME_TMP_DIR + * \param [in,out] libraryFile - holds the URL and returns name of a downloaded file + * \param [out] error - return error description + * \return bool - is a success + */ + //================================================================================ + + bool downloadLib( LibraryFile& libraryFile, std::string & error ) + { + // check if can write into SALOME_TMP_DIR + + std::string tmpDir = Kernel_Utils::GetTmpDirByEnv( theTmpEnvVar ); + if ( tmpDir.empty() || + !Kernel_Utils::IsExists( tmpDir )) + { + error = "Can't download " + libraryFile._name + " as SALOME_TMP_DIR is not correctly set"; + return false; + } + if ( !Kernel_Utils::IsWritable( tmpDir )) + { + error = "Can't download " + libraryFile._name + " as '" + tmpDir + "' is not writable. " + "Check SALOME_TMP_DIR environment variable"; + return false; + } + + // Download + + std::string url = libraryFile._name; + +#ifdef WIN32 + + std::string outFile = tmpDir + "MeshGemsKeyGenerator.dll"; + + // use wget (== Invoke-WebRequest) PowerShell command available since Windows 7 + std::string psCmd = "wget -Uri " + url + " -OutFile " + outFile; + std::string cmd = "powershell.exe " + psCmd; + +#else + + std::string outFile = tmpDir + "libMeshGemsKeyGenerator.so"; + + std::string cmd = "wget " + url + " -O " + outFile; + +#endif + + if ( Kernel_Utils::IsExists( outFile )) // remove existing file + { + SMESH_File lib( outFile, /*open=*/false ); + if ( !lib.remove() ) + { + error = lib.error(); + return false; + } + } + + system( cmd.c_str() ); // download + + SMESH_File resultFile( outFile, /*open=*/false ); + bool ok = ( resultFile.exists() && resultFile.size() > 0 ); + + if ( ok ) + libraryFile._name = outFile; + else + error = "Can't download file " + url; + + return ok; + } + + //================================================================================ + /*! + * \brief Load libMeshGemsKeyGenerator.so + * \param [out] error - return error description + * \param [out] libraryFile - return library file name and _isURL flag + * \return bool - is a success + */ + //================================================================================ + + bool loadLibrary( std::string& error, LibraryFile& libraryFile ) + { + if ( theLibraryHandle ) + return true; + + const char* libPath = getenv( theEnvVar ); + if ( !libPath ) + { + error = SMESH_Comment( "Environment variable ") << theEnvVar << " is not set"; + return false; + } + + libraryFile._name = libPath; + // if ( !setExtension( libraryFile._name, error )) // is it necessary? + // return false; + + if ( isURL( libraryFile )) + { + if ( !downloadLib( libraryFile, error )) + { + // try to fix extension + std::string url = libraryFile._name; + if ( !setExtension( libraryFile._name, error )) + return false; + if ( url == libraryFile._name ) + return false; // extension not changed + + if ( !downloadLib( libraryFile, error )) + return false; + } + } + +#if defined( WIN32 ) && defined( UNICODE ) + std::wstring encodePath = Kernel_Utils::utf8_decode_s( libraryFile._name ); + const wchar_t* path = encodePath.c_str(); +#else + const char* path = libraryFile._name.c_str(); +#endif + + theLibraryHandle = LoadLib( path ); + if ( !theLibraryHandle ) + { + if ( ! getLastError( error )) + error = "Can't load library '" + libraryFile._name + "'"; + } + + return theLibraryHandle; + } + +} // anonymous namespace + + +namespace SMESHUtils_MGLicenseKeyGen // API implementation +{ + //================================================================================ + /*! + * \brief Sign a CAD + * \param [in] meshgems_cad - pointer to a MG CAD object (meshgems_cad_t) + * \param [out] error - return error description + * \return bool - is a success + */ + //================================================================================ + + bool SignCAD( void* meshgems_cad, std::string& error ) + { + LibraryFile libraryFile; + if ( !loadLibrary( error, libraryFile )) + return false; + + bool ok = false; + typedef bool (*SignFun)(void* ); + SignFun signFun = (SignFun) GetProc( theLibraryHandle, "SignCAD" ); + if ( !signFun ) + { + if ( ! getLastError( error )) + error = SMESH_Comment( "Can't find symbol 'SignCAD' in '") << getenv( theEnvVar ) << "'"; + } + else + { + SMESH_TRY; + + ok = signFun( meshgems_cad ); + + SMESH_CATCH( SMESH::returnError ); + + if ( !error.empty() ) + ok = false; + else if ( !ok ) + error = "SignCAD() failed (located in '" + libraryFile._name + "')"; + } + return ok; + } + + //================================================================================ + /*! + * \brief Sign a mesh + * \param [in] meshgems_mesh - pointer to a MG mesh (meshgems_mesh_t) + * \param [out] error - return error description + * \return bool - is a success + */ + //================================================================================ + + bool SignMesh( void* meshgems_mesh, std::string& error ) + { + LibraryFile libraryFile; + if ( !loadLibrary( error, libraryFile )) + return false; + + bool ok = false; + typedef bool (*SignFun)(void* ); + SignFun signFun = (SignFun) GetProc( theLibraryHandle, "SignMesh" ); + if ( !signFun ) + { + if ( ! getLastError( error )) + error = SMESH_Comment( "Can't find symbol 'SignMesh' in '") << getenv( theEnvVar ) << "'"; + } + else + { + SMESH_TRY; + + ok = signFun( meshgems_mesh ); + + SMESH_CATCH( SMESH::returnError ); + + if ( !error.empty() ) + ok = false; + else if ( !ok ) + error = "SignMesh() failed (located in '" + libraryFile._name + "')"; + } + return ok; + } + + //================================================================================ + /*! + * \brief Return a license key to pass as argument to a MG mesher executable + * \param [in] gmfFile - path to an input mesh file + * \param [in] nb* - nb of entities in the input mesh + * \param [out] error - return error description + * \return std::string - the key + */ + //================================================================================ + + std::string GetKey(const std::string& gmfFile, + int nbVertex, + int nbEdge, + int nbFace, + int nbVol, + std::string& error) + { + std::string key; + LibraryFile libraryFile; + if ( !loadLibrary( error, libraryFile )) + return key; + + typedef std::string (*GetKeyFun)(std::string const &, int, int, int, int ); + GetKeyFun keyFun = (GetKeyFun) GetProc( theLibraryHandle, "GetKey" ); + if ( !keyFun ) + { + if ( ! getLastError( error )) + error = SMESH_Comment( "Can't find symbol 'GetKey' in '") << getenv( theEnvVar ) << "'"; + } + else + { + key = keyFun( gmfFile, nbVertex, nbEdge, nbFace, nbVol ); + } + if ( key.empty() ) + error = "GetKey() failed (located in '" + libraryFile._name + "')"; + + return key; + } + + //================================================================================ + /*! + * \brief Return false if libMeshGemsKeyGenerator.so is not functional + * \param [out] error - return error description + * \return bool - is a success + */ + //================================================================================ + + bool CheckKeyGenLibrary( std::string& error ) + { + return !GetKey("",4,0,2,0,error ).empty(); + } + + //================================================================================ + /*! + * \brief Return KeyGenerator library name + */ + //================================================================================ + + std::string GetLibraryName() + { + std::string libName, error; + if ( const char* libPath = getenv( theEnvVar )) + { + libName = Kernel_Utils::GetBaseName( libPath ); + } + else + { + libName = "libSalomeMeshGemsKeyGenerator"; + } + setExtension( libName, error ); + return libName; + } +} diff --git a/src/SMESHUtils/SMESH_MGLicenseKeyGen.hxx b/src/SMESHUtils/SMESH_MGLicenseKeyGen.hxx new file mode 100644 index 000000000..796cde4b5 --- /dev/null +++ b/src/SMESHUtils/SMESH_MGLicenseKeyGen.hxx @@ -0,0 +1,52 @@ +// Copyright (C) 2007-2021 CEA/DEN, EDF R&D, OPEN CASCADE +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// +// File : SMESH_MGLicenseKeyGen.hxx +// Created : Sat Jul 31 18:41:04 2021 +// Author : Edward AGAPOV (OCC) + +#ifndef __SMESHUtils_MGLicenseKeyGen_HXX__ +#define __SMESHUtils_MGLicenseKeyGen_HXX__ + +#include "SMESH_Utils.hxx" + +#include + +/*! + * \brief Manage loading libSalomeMeshGemsKeyGenerator.[so|dll] and sing MeshGems CAD or mesh + */ + +namespace SMESHUtils_MGLicenseKeyGen +{ + SMESHUtils_EXPORT bool SignCAD( void* meshgems_cad, std::string& error ); + + SMESHUtils_EXPORT bool SignMesh( void* meshgems_mesh, std::string& error ); + + SMESHUtils_EXPORT std::string GetKey(const std::string& gmfFile, + int nbVertex, + int nbEdge, + int nbFace, + int nbVol, + std::string& error); + + SMESHUtils_EXPORT bool CheckKeyGenLibrary( std::string& error ); + + SMESHUtils_EXPORT std::string GetLibraryName(); +} + +#endif diff --git a/src/SMESH_I/SMESH_2smeshpy.cxx b/src/SMESH_I/SMESH_2smeshpy.cxx index bd0ec817e..07b3d3399 100644 --- a/src/SMESH_I/SMESH_2smeshpy.cxx +++ b/src/SMESH_I/SMESH_2smeshpy.cxx @@ -1024,7 +1024,6 @@ void _pyGen::Process( const Handle(_pyCommand)& theCommand ) return; } if ( method == "CreateMeshesFromMED" || - method == "CreateMeshesFromSAUV"|| method == "CreateMeshesFromCGNS" || method == "CreateMeshesFromGMF" ) // command result is ( [mesh1,mesh2], status ) { @@ -2194,7 +2193,7 @@ bool _pyMesh::NeedMeshAccess( const Handle(_pyCommand)& theCommand ) static TStringSet sameMethods; if ( sameMethods.empty() ) { const char * names[] = - { "ExportDAT","ExportUNV","ExportSTL","ExportSAUV", "RemoveGroup","RemoveGroupWithContents", + { "ExportDAT","ExportUNV","ExportSTL", "RemoveGroup","RemoveGroupWithContents", "GetGroups","UnionGroups","IntersectGroups","CutGroups","CreateDimGroup","GetLog","GetId", "ClearLog","HasDuplicatedGroupNamesMED","GetMEDMesh","NbNodes","NbElements", "NbEdges","NbEdgesOfOrder","NbFaces","NbFacesOfOrder","NbTriangles", @@ -2490,8 +2489,8 @@ void _pyMeshEditor::Process( const Handle(_pyCommand)& theCommand) "RemoveElements","RemoveNodes","RemoveOrphanNodes", "AddNode","Add0DElement","AddEdge","AddFace","AddPolygonalFace","AddBall", "AddVolume","AddPolyhedralVolume","AddPolyhedralVolumeByFaces", - "MoveNode", "MoveClosestNodeToPoint", - "InverseDiag","DeleteDiag","Reorient","ReorientObject","Reorient2DBy3D", + "MoveNode", "MoveClosestNodeToPoint","InverseDiag","DeleteDiag", + "Reorient","ReorientObject","Reorient2DBy3D","Reorient2DByNeighbours", "TriToQuad","TriToQuadObject", "QuadTo4Tri", "SplitQuad","SplitQuadObject", "BestSplit","Smooth","SmoothObject","SmoothParametric","SmoothParametricObject", "ConvertToQuadratic","ConvertFromQuadratic","RenumberNodes","RenumberElements", diff --git a/src/SMESH_I/SMESH_Gen_i.cxx b/src/SMESH_I/SMESH_Gen_i.cxx index 30d035262..9fce23337 100644 --- a/src/SMESH_I/SMESH_Gen_i.cxx +++ b/src/SMESH_I/SMESH_Gen_i.cxx @@ -145,7 +145,6 @@ #include #include -#include #include #include @@ -190,22 +189,22 @@ PortableServer::ServantBase_var SMESH_Gen_i::GetServant( CORBA::Object_ptr theOb } catch (PortableServer::POA::ObjectNotActive &ex) { - INFOS("GetServant: ObjectNotActive"); + MESSAGE("GetServant: ObjectNotActive"); return NULL; } catch (PortableServer::POA::WrongAdapter &ex) { - INFOS("GetServant: WrongAdapter: OK when several servants used to build several mesh in parallel..."); + MESSAGE("GetServant: WrongAdapter: OK when several servants used to build several mesh in parallel..."); return NULL; } catch (PortableServer::POA::WrongPolicy &ex) { - INFOS("GetServant: WrongPolicy"); + MESSAGE("GetServant: WrongPolicy"); return NULL; } catch (...) { - INFOS( "GetServant - Unknown exception was caught!!!" ); + MESSAGE( "GetServant - Unknown exception was caught!!!" ); return NULL; } } @@ -1317,17 +1316,17 @@ SMESH::SMESH_Mesh_ptr SMESH_Gen_i::CreateMeshesFromUNV( const char* theFileName */ //============================================================================= -SMESH::mesh_array* SMESH_Gen_i::CreateMeshesFromMEDorSAUV( const char* theFileName, - SMESH::DriverMED_ReadStatus& theStatus, - const char* theCommandNameForPython, - const char* theFileNameForPython) +SMESH::mesh_array* SMESH_Gen_i::CreateMeshesFromMED( const char* theFileName, + SMESH::DriverMED_ReadStatus& theStatus ) { + checkFileReadable( theFileName ); + #ifdef WIN32 char bname[ _MAX_FNAME ]; - _splitpath( theFileNameForPython, NULL, NULL, bname, NULL ); + _splitpath( theFileName, NULL, NULL, bname, NULL ); string aFileName = bname; #else - string aFileName = basename( const_cast(theFileNameForPython) ); + string aFileName = basename( const_cast( theFileName )); #endif // Retrieve mesh names from the file DriverMED_R_SMESHDS_Mesh myReader; @@ -1340,59 +1339,57 @@ SMESH::mesh_array* SMESH_Gen_i::CreateMeshesFromMEDorSAUV( const char* theFileNa { // open a new scope to make aPythonDump die before PythonDump in SMESH_Mesh::GetGroups() - // Python Dump - TPythonDump aPythonDump(this); - aPythonDump << "(["; + // Python Dump + TPythonDump aPythonDump(this); + aPythonDump << "(["; - if (theStatus == SMESH::DRS_OK) { - SALOMEDS::StudyBuilder_var aStudyBuilder; - aStudyBuilder = getStudyServant()->NewBuilder(); - aStudyBuilder->NewCommand(); // There is a transaction - - aResult->length( aNames.size() ); - int i = 0; - - // Iterate through all meshes and create mesh objects - for ( list::iterator it = aNames.begin(); it != aNames.end(); it++ ) + if (theStatus == SMESH::DRS_OK) { - // Python Dump - if (i > 0) aPythonDump << ", "; + SALOMEDS::StudyBuilder_var aStudyBuilder; + aStudyBuilder = getStudyServant()->NewBuilder(); + aStudyBuilder->NewCommand(); // There is a transaction - // create mesh - SMESH::SMESH_Mesh_var mesh = createMesh(); + aResult->length( aNames.size() ); + int i = 0; - // publish mesh in the study - SALOMEDS::SObject_wrap aSO; - if ( CanPublishInStudy( mesh ) ) - // little trick: for MED file theFileName and theFileNameForPython are the same, but they are different for SAUV - // - as names of meshes are stored in MED file, we use them for data publishing - // - as mesh name is not stored in UNV file, we use file name as name of mesh when publishing data - aSO = PublishMesh( mesh.in(), ( theFileName == theFileNameForPython ) ? (*it).c_str() : aFileName.c_str() ); + // Iterate through all meshes and create mesh objects + for ( const std::string & meshName : aNames ) + { + // Python Dump + if (i > 0) aPythonDump << ", "; - // Python Dump - if ( !aSO->_is_nil() ) { - aPythonDump << aSO; - } else { - aPythonDump << "mesh_" << i; + // create mesh + SMESH::SMESH_Mesh_var mesh = createMesh(); + + // publish mesh in the study + SALOMEDS::SObject_wrap aSO; + if ( CanPublishInStudy( mesh ) ) + aSO = PublishMesh( mesh.in(), meshName.c_str() ); + + // Python Dump + if ( !aSO->_is_nil() ) { + aPythonDump << aSO; + } else { + aPythonDump << "mesh_" << i; + } + + // Read mesh data (groups are published automatically by ImportMEDFile()) + SMESH_Mesh_i* meshServant = dynamic_cast( GetServant( mesh ).in() ); + ASSERT( meshServant ); + SMESH::DriverMED_ReadStatus status1 = + meshServant->ImportMEDFile( theFileName, meshName.c_str() ); + if (status1 > theStatus) + theStatus = status1; + + aResult[i++] = SMESH::SMESH_Mesh::_duplicate( mesh ); + meshServant->GetImpl().GetMeshDS()->Modified(); } - - // Read mesh data (groups are published automatically by ImportMEDFile()) - SMESH_Mesh_i* meshServant = dynamic_cast( GetServant( mesh ).in() ); - ASSERT( meshServant ); - SMESH::DriverMED_ReadStatus status1 = - meshServant->ImportMEDFile( theFileName, (*it).c_str() ); - if (status1 > theStatus) - theStatus = status1; - - aResult[i++] = SMESH::SMESH_Mesh::_duplicate( mesh ); - meshServant->GetImpl().GetMeshDS()->Modified(); + if ( !aStudyBuilder->_is_nil() ) + aStudyBuilder->CommitCommand(); } - if ( !aStudyBuilder->_is_nil() ) - aStudyBuilder->CommitCommand(); - } - // Update Python script - aPythonDump << "], status) = " << this << "." << theCommandNameForPython << "(r'" << theFileNameForPython << "')"; + // Update Python script + aPythonDump << "], status) = " << this << ".CreateMeshesFromMED( r'" << theFileName << "' )"; } // Dump creation of groups for ( CORBA::ULong i = 0; i < aResult->length(); ++i ) @@ -1401,66 +1398,6 @@ SMESH::mesh_array* SMESH_Gen_i::CreateMeshesFromMEDorSAUV( const char* theFileNa return aResult._retn(); } -//================================================================================ -/*! - * \brief Create meshes by reading a MED file - */ -//================================================================================ - -SMESH::mesh_array* SMESH_Gen_i::CreateMeshesFromMED( const char* theFileName, - SMESH::DriverMED_ReadStatus& theStatus) -{ - Unexpect aCatch(SALOME_SalomeException); - checkFileReadable( theFileName ); - - SMESH::mesh_array* result = CreateMeshesFromMEDorSAUV(theFileName, theStatus, - "CreateMeshesFromMED", theFileName); - return result; -} - -//============================================================================= -/*! - * SMESH_Gen_i::CreateMeshFromSAUV - * - * Create mesh and import data from SAUV file - */ -//============================================================================= - -SMESH::mesh_array* SMESH_Gen_i::CreateMeshesFromSAUV( const char* theFileName, - SMESH::DriverMED_ReadStatus& theStatus) -{ - Unexpect aCatch(SALOME_SalomeException); - checkFileReadable( theFileName ); - - std::string sauvfilename(theFileName); - std::string medfilename(theFileName); - medfilename += ".med"; - std::string cmd; -#ifdef WIN32 - cmd = "%PYTHONBIN% "; -#else - cmd = "python3 "; -#endif - cmd += "-c \""; - cmd += "from medutilities import convert ; convert(r'" + sauvfilename + "', 'GIBI', 'MED', 1, r'" + medfilename + "')"; - cmd += "\""; - system(cmd.c_str()); - SMESH::mesh_array* result = CreateMeshesFromMEDorSAUV(medfilename.c_str(), - theStatus, - "CreateMeshesFromSAUV", - sauvfilename.c_str()); -#ifdef WIN32 - cmd = "%PYTHONBIN% "; -#else - cmd = "python3 "; -#endif - cmd += "-c \""; - cmd += "from medutilities import my_remove ; my_remove(r'" + medfilename + "')"; - cmd += "\""; - system(cmd.c_str()); - return result; -} - //============================================================================= /*! * SMESH_Gen_i::CreateMeshFromSTL diff --git a/src/SMESH_I/SMESH_Gen_i.hxx b/src/SMESH_I/SMESH_Gen_i.hxx index 648b1d2f5..9caaa543c 100644 --- a/src/SMESH_I/SMESH_Gen_i.hxx +++ b/src/SMESH_I/SMESH_Gen_i.hxx @@ -241,10 +241,6 @@ public: SMESH::mesh_array* CreateMeshesFromMED( const char* theFileName, SMESH::DriverMED_ReadStatus& theStatus ); - // Create mesh(es) and import data from MED file - SMESH::mesh_array* CreateMeshesFromSAUV( const char* theFileName, - SMESH::DriverMED_ReadStatus& theStatus ); - // Create a mesh and import data from a STL file SMESH::SMESH_Mesh_ptr CreateMeshesFromSTL( const char* theFileName ); @@ -641,11 +637,6 @@ private: void highLightInvalid( SALOMEDS::SObject_ptr theSObject, bool isInvalid ); - SMESH::mesh_array* CreateMeshesFromMEDorSAUV( const char* theFileName, - SMESH::DriverMED_ReadStatus& theStatus, - const char* theCommandNameForPython, - const char* theFileNameForPython); - std::vector _GetInside(SMESH::SMESH_IDSource_ptr meshPart, SMESH::ElementType ElemType, const TopoDS_Shape& Shape, diff --git a/src/SMESH_I/SMESH_MeshEditor_i.cxx b/src/SMESH_I/SMESH_MeshEditor_i.cxx index f11615845..323a6603a 100644 --- a/src/SMESH_I/SMESH_MeshEditor_i.cxx +++ b/src/SMESH_I/SMESH_MeshEditor_i.cxx @@ -1696,7 +1696,8 @@ CORBA::Long SMESH_MeshEditor_i::Reorient2D(SMESH::SMESH_IDSource_ptr the2Dgroup, if ( dirVec.Magnitude() < std::numeric_limits< double >::min() ) THROW_SALOME_CORBA_EXCEPTION("Zero size vector", SALOME::BAD_PARAM); - int nbReori = getEditor().Reorient2D( elements, dirVec, face ); + TIDSortedElemSet refFaces = { face }; + int nbReori = getEditor().Reorient2D( elements, dirVec, refFaces, /*allowNonManifold=*/true ); if ( nbReori ) { declareMeshModified( /*isReComputeSafe=*/false ); @@ -1713,6 +1714,64 @@ CORBA::Long SMESH_MeshEditor_i::Reorient2D(SMESH::SMESH_IDSource_ptr the2Dgroup, return 0; } +//======================================================================= +//function : Reorient2DByNeighbours +//purpose : Reorient faces contained in a list of objectFaces +// equally to faces contained in a list of referenceFaces. +//======================================================================= + +CORBA::Long +SMESH_MeshEditor_i::Reorient2DByNeighbours(const SMESH::ListOfIDSources& theObjectFaces, + const SMESH::ListOfIDSources& theReferenceFaces) +{ + SMESH_TRY; + initData(/*deleteSearchers=*/false); + + if ( theObjectFaces.length() == 0 ) + return 0; + + // get object faces + TIDSortedElemSet objFaces; + bool invalidObjFaces = false; + for ( CORBA::ULong i = 0; i < theObjectFaces.length(); ++i ) + { + IDSource_Error err; + if ( !idSourceToSet( theObjectFaces[i], getMeshDS(), objFaces, SMDSAbs_Face, + /*emptyIfIsMesh=*/1, &err ) && + err == IDSource_INVALID ) + invalidObjFaces = true; + } + if ( objFaces.empty() && invalidObjFaces ) + THROW_SALOME_CORBA_EXCEPTION("No valid faces in given groups", SALOME::BAD_PARAM); + + // get reference faces + TIDSortedElemSet refFaces; + for ( CORBA::ULong i = 0; i < theReferenceFaces.length(); ++i ) + { + idSourceToSet( theReferenceFaces[i], getMeshDS(), refFaces, SMDSAbs_Face, /*emptyIfIsMesh=*/1 ); + } + if ( refFaces.empty() && theReferenceFaces.length() > 0 ) + THROW_SALOME_CORBA_EXCEPTION("Reference faces are invalid", SALOME::BAD_PARAM); + + + gp_Vec zeroVec( 0,0,0 ); + + // reorient + int nbReori = getEditor().Reorient2D( objFaces, zeroVec, refFaces, /*allowNonManifold=*/false ); + + if ( nbReori ) + declareMeshModified( /*isReComputeSafe=*/false ); + + TPythonDump() << this << ".Reorient2DByNeighbours(" + << theObjectFaces << ", " + << theReferenceFaces << ")"; + + return nbReori; + + SMESH_CATCH( SMESH::throwCorbaException ); + return 0; +} + //======================================================================= //function : Reorient2DBy3D //purpose : Reorient faces basing on orientation of adjacent volumes. diff --git a/src/SMESH_I/SMESH_MeshEditor_i.hxx b/src/SMESH_I/SMESH_MeshEditor_i.hxx index 69f62d539..3d7072ed4 100644 --- a/src/SMESH_I/SMESH_MeshEditor_i.hxx +++ b/src/SMESH_I/SMESH_MeshEditor_i.hxx @@ -192,6 +192,17 @@ public: const SMESH::DirStruct& theDirection, CORBA::Long theFace, const SMESH::PointStruct& thePoint); + /*! + * \brief Reorient faces contained in a list of \a objectFaces + * equally to faces contained in a list of \a referenceFaces. + * \param objectFaces - faces to reorient in a list including either + * the whole mesh or groups and/or sub-meshes. + * \param referenceFaces - correctly oriented faces in a list of groups and/or sub-meshes. + * It can be empty, then the 1st face in \a objectFaces is used as the reference. + * \return number of reoriented faces. + */ + CORBA::Long Reorient2DByNeighbours(const SMESH::ListOfIDSources& objectFaces, + const SMESH::ListOfIDSources& referenceFaces); /*! * \brief Reorient faces basing on orientation of adjacent volumes. * \param faces - a list of objects containing face to reorient diff --git a/src/SMESH_I/SMESH_Mesh_i.cxx b/src/SMESH_I/SMESH_Mesh_i.cxx index c63eccd3b..99e45c66e 100644 --- a/src/SMESH_I/SMESH_Mesh_i.cxx +++ b/src/SMESH_I/SMESH_Mesh_i.cxx @@ -3797,27 +3797,6 @@ CORBA::LongLong SMESH_Mesh_i::ExportMEDCoupling(CORBA::Boolean auto_groups, CORB return reinterpret_cast(ret); } -//================================================================================ -/*! - * \brief Export a mesh to a SAUV file - */ -//================================================================================ - -void SMESH_Mesh_i::ExportSAUV( const char* file, CORBA::Boolean auto_groups ) -{ - SMESH_TRY; - if ( _preMeshInfo ) - _preMeshInfo->FullLoadFromFile(); - - string aMeshName = prepareMeshNameAndGroups(file, true); - TPythonDump() << SMESH::SMESH_Mesh_var( _this()) - << ".ExportSAUV( r'" << file << "', " << auto_groups << " )"; - _impl->ExportSAUV(file, aMeshName.c_str(), auto_groups); - - SMESH_CATCH( SMESH::throwCorbaException ); -} - - //================================================================================ /*! * \brief Export a mesh to a DAT file diff --git a/src/SMESH_I/SMESH_Mesh_i.hxx b/src/SMESH_I/SMESH_Mesh_i.hxx index a2c428656..36e18d1be 100644 --- a/src/SMESH_I/SMESH_Mesh_i.hxx +++ b/src/SMESH_I/SMESH_Mesh_i.hxx @@ -215,8 +215,6 @@ public: 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, const CORBA::Boolean renumber ); void ExportUNV( const char* file, const CORBA::Boolean renumber ); void ExportSTL( const char* file, bool isascii ); diff --git a/src/SMESH_PY/CMakeLists.txt b/src/SMESH_PY/CMakeLists.txt index b6b47fa56..2150a6363 100644 --- a/src/SMESH_PY/CMakeLists.txt +++ b/src/SMESH_PY/CMakeLists.txt @@ -21,10 +21,10 @@ # scripts / static SET(_bin_SCRIPTS - __init__.py smeshstudytools.py ) # --- rules --- -SALOME_INSTALL_SCRIPTS("${_bin_SCRIPTS}" ${SALOME_INSTALL_PYTHON}/salome/smesh) \ No newline at end of file +SALOME_INSTALL_SCRIPTS("${_bin_SCRIPTS}" ${SALOME_INSTALL_PYTHON}/salome/smesh) +SALOME_CONFIGURE_FILE(__init__.py __init__.py INSTALL ${SALOME_INSTALL_PYTHON}/salome/smesh) diff --git a/src/SMESH_PY/__init__.py b/src/SMESH_PY/__init__.py index 965aaa4fb..0d138181a 100644 --- a/src/SMESH_PY/__init__.py +++ b/src/SMESH_PY/__init__.py @@ -18,3 +18,4 @@ # See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com # +__version__ = "@SALOMESMESH_GIT_SHA1@" diff --git a/src/SMESH_SWIG/CMakeLists.txt b/src/SMESH_SWIG/CMakeLists.txt index 53b87e321..bd3a578d4 100644 --- a/src/SMESH_SWIG/CMakeLists.txt +++ b/src/SMESH_SWIG/CMakeLists.txt @@ -25,6 +25,8 @@ include_directories( ${PROJECT_SOURCE_DIR}/src/SMDS ${PROJECT_SOURCE_DIR}/src/SMESH ${PROJECT_SOURCE_DIR}/src/SMESH_I + ${PROJECT_SOURCE_DIR}/src/Driver + ${PROJECT_SOURCE_DIR}/src/DriverGMF ${CMAKE_CURRENT_SOURCE_DIR} ${PROJECT_BINARY_DIR}/idl ) @@ -123,7 +125,7 @@ IF(${CMAKE_VERSION} VERSION_LESS "3.8.0") ELSE() SWIG_ADD_LIBRARY(SMeshHelper LANGUAGE python SOURCES ${SMeshHelper_SOURCES}) ENDIF() -SWIG_LINK_LIBRARIES(SMeshHelper ${PYTHON_LIBRARIES} ${PLATFORM_LIBS} SMESHEngine ) +SWIG_LINK_LIBRARIES(SMeshHelper ${PYTHON_LIBRARIES} ${PLATFORM_LIBS} SMESHEngine MeshDriverGMF ) SWIG_CHECK_GENERATION(SMeshHelper) IF(WIN32) SET_TARGET_PROPERTIES(_SMeshHelper PROPERTIES DEBUG_OUTPUT_NAME _SMeshHelper_d) diff --git a/src/SMESH_SWIG/SMeshHelper.cxx b/src/SMESH_SWIG/SMeshHelper.cxx index ee2d54b05..92991e20c 100644 --- a/src/SMESH_SWIG/SMeshHelper.cxx +++ b/src/SMESH_SWIG/SMeshHelper.cxx @@ -25,9 +25,35 @@ #include +#include +#include + + std::string BuildSMESHInstanceInternal() { Engines::EngineComponent_var zeRef = RetrieveSMESHInstance(); CORBA::String_var ior = KERNEL::getORB()->object_to_string(zeRef); return std::string(ior.in()); } + +std::string GetMGLicenseKeyImpl(const char* gmfFile) +{ + smIdType nbVertex, nbEdge, nbFace, nbVol; + DriverGMF_Read gmfReader; + gmfReader.SetFile( gmfFile ); + gmfReader.GetMeshInfo( nbVertex, nbEdge, nbFace, nbVol ); + + std::string errorTxt; + std::string key = SMESHUtils_MGLicenseKeyGen::GetKey( gmfFile, + FromSmIdType( nbVertex ), + FromSmIdType( nbEdge ), + FromSmIdType( nbFace ), + FromSmIdType( nbVol ), + errorTxt ); + if ( !errorTxt.empty() ) + { + std::cerr << "Error: Pb with MeshGems license: " << errorTxt << std::endl; + key = "<" + errorTxt + ">"; + } + return key; +} diff --git a/src/SMESH_SWIG/SMeshHelper.h b/src/SMESH_SWIG/SMeshHelper.h index 58b2c5321..9c912869e 100644 --- a/src/SMESH_SWIG/SMeshHelper.h +++ b/src/SMESH_SWIG/SMeshHelper.h @@ -22,3 +22,5 @@ #include std::string BuildSMESHInstanceInternal(); + +std::string GetMGLicenseKeyImpl(const char* gmfFile); diff --git a/src/SMESH_SWIG/SMeshHelper.i b/src/SMESH_SWIG/SMeshHelper.i index b73a87db9..d1220cb90 100644 --- a/src/SMESH_SWIG/SMeshHelper.i +++ b/src/SMESH_SWIG/SMeshHelper.i @@ -31,4 +31,9 @@ { return BuildSMESHInstanceInternal(); } + + std::string GetMGLicenseKey(const char* gmfFile) + { + return GetMGLicenseKeyImpl( gmfFile ); + } } diff --git a/src/SMESH_SWIG/smeshBuilder.py b/src/SMESH_SWIG/smeshBuilder.py index 820e2e1af..1d5269c19 100644 --- a/src/SMESH_SWIG/smeshBuilder.py +++ b/src/SMESH_SWIG/smeshBuilder.py @@ -685,18 +685,6 @@ class smeshBuilder( SMESH._objref_SMESH_Gen, object ): aMeshes = [ Mesh(self, self.geompyD, m) for m in aSmeshMeshes ] return aMeshes, aStatus - def CreateMeshesFromSAUV( self,theFileName ): - """ - Create a Mesh object(s) importing data from the given SAUV file - - Returns: - a tuple ( list of class :class:`Mesh` instances, :class:`SMESH.DriverMED_ReadStatus` ) - """ - - aSmeshMeshes, aStatus = SMESH._objref_SMESH_Gen.CreateMeshesFromSAUV(self,theFileName) - aMeshes = [ Mesh(self, self.geompyD, m) for m in aSmeshMeshes ] - return aMeshes, aStatus - def CreateMeshesFromSTL( self, theFileName ): """ Create a Mesh object importing data from the given STL file @@ -2456,20 +2444,6 @@ class Mesh(metaclass = MeshMeta): else: self.mesh.ExportMED(fileName, auto_groups, version, overwrite, autoDimension) - def ExportSAUV(self, f, auto_groups=0): - """ - Export the mesh in a file in SAUV format - - - Parameters: - f: is the file name - 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. - """ - - self.mesh.ExportSAUV(f, auto_groups) - def ExportDAT(self, f, meshPart=None, renumber=True): """ Export the mesh in a file in DAT format @@ -4690,6 +4664,29 @@ class Mesh(metaclass = MeshMeta): theFace = -1 return self.editor.Reorient2D( the2DObject, theDirection, theFace, thePoint ) + def Reorient2DByNeighbours(self, objectFaces, referenceFaces=[]): + """ + Reorient faces contained in a list of *objectFaces* + equally to faces contained in a list of *referenceFaces*. + + Parameters: + objectFaces: list of :class:`mesh, sub-mesh, group, filter ` holding faces to reorient. + referenceFaces: list of :class:`sub-mesh, group, filter ` holding reference faces. It can be empty, then any face in *objectFaces* is used as the reference. + + Returns: + number of reoriented faces. + """ + if not isinstance( objectFaces, list ): + objectFaces = [ objectFaces ] + for i,obj2D in enumerate( objectFaces ): + if isinstance( obj2D, Mesh ): + objectFaces[i] = obj2D.GetMesh() + if not isinstance( referenceFaces, list ): + referenceFaces = [ referenceFaces ] + + return self.editor.Reorient2DByNeighbours( objectFaces, referenceFaces ) + + def Reorient2DBy3D(self, the2DObject, the3DObject, theOutsideNormal=True ): """ Reorient faces according to adjacent volumes. diff --git a/src/SalomeSessionless/CMakeLists.txt b/src/SalomeSessionless/CMakeLists.txt index b21eaa20e..dc1c5dc95 100644 --- a/src/SalomeSessionless/CMakeLists.txt +++ b/src/SalomeSessionless/CMakeLists.txt @@ -19,6 +19,7 @@ SET(_bin_SCRIPTS SMESH_SalomeSessionless.py + MeshJobManager_SalomeSessionless.py ) SALOME_INSTALL_SCRIPTS("${_bin_SCRIPTS}" ${SALOME_INSTALL_PYTHON} DEF_PERMS) diff --git a/src/SalomeSessionless/MeshJobManager_SalomeSessionless.py b/src/SalomeSessionless/MeshJobManager_SalomeSessionless.py new file mode 100644 index 000000000..50f5d1fab --- /dev/null +++ b/src/SalomeSessionless/MeshJobManager_SalomeSessionless.py @@ -0,0 +1,28 @@ +# -*- coding: iso-8859-1 -*- +# Copyright (C) 2021 CEA/DEN, EDF R&D, OPEN CASCADE +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# +# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +# + +def buildInstance(orb): + import SMeshPadderHelper + padder_ior = SMeshPadderHelper.BuildPadderMeshJobManagerInstance() + import MESHJOB + import CORBA + orb=CORBA.ORB_init(['']) + padderInst = orb.string_to_object(padder_ior) + return padderInst, orb diff --git a/src/StdMeshers/StdMeshers_Cartesian_3D.cxx b/src/StdMeshers/StdMeshers_Cartesian_3D.cxx index dc82aa09a..346372a6f 100644 --- a/src/StdMeshers/StdMeshers_Cartesian_3D.cxx +++ b/src/StdMeshers/StdMeshers_Cartesian_3D.cxx @@ -4458,7 +4458,7 @@ namespace // connect pn2 (probably new, at _eIntNodes) with a split - int i, iConn; + int i, iConn = 0; size_t nbCommon; TGeomID commonFaces[20]; _Node* nPrev = nullptr; @@ -5644,8 +5644,8 @@ namespace continue; gp_Dir direction(1,0,0); - const SMDS_MeshElement* anyFace = *facesToOrient.begin(); - editor.Reorient2D( facesToOrient, direction, anyFace ); + TIDSortedElemSet refFaces; + editor.Reorient2D( facesToOrient, direction, refFaces, /*allowNonManifold=*/true ); } } return; diff --git a/src/StdMeshers/StdMeshers_MEFISTO_2D.cxx b/src/StdMeshers/StdMeshers_MEFISTO_2D.cxx index 48b07193e..0222fa7e2 100644 --- a/src/StdMeshers/StdMeshers_MEFISTO_2D.cxx +++ b/src/StdMeshers/StdMeshers_MEFISTO_2D.cxx @@ -637,7 +637,11 @@ bool StdMeshers_MEFISTO_2D::LoadPoints(TWireVector & wires, m++; } - int mFirst = mOnVertex.front(), mLast = m - 1; + int mFirst = 0, mLast = 0; + if (!mOnVertex.empty()) { + mFirst = mOnVertex.front(); + mLast = m - 1; + } list< int >::iterator mIt = mOnVertex.begin(); for ( ; mIt != mOnVertex.end(); ++mIt) { diff --git a/src/StdMeshers/StdMeshers_Projection_2D.cxx b/src/StdMeshers/StdMeshers_Projection_2D.cxx index bbc874cf9..3e889f080 100644 --- a/src/StdMeshers/StdMeshers_Projection_2D.cxx +++ b/src/StdMeshers/StdMeshers_Projection_2D.cxx @@ -775,7 +775,7 @@ namespace { // check node positions - if ( !tgtFace.IsPartner( srcFace ) ) + // if ( !tgtFace.IsPartner( srcFace ) ) for NETGEN 6 which sets wrong UV { helper->ToFixNodeParameters( true ); diff --git a/src/StdMeshers/StdMeshers_ViscousLayers.cxx b/src/StdMeshers/StdMeshers_ViscousLayers.cxx index fa4853668..552995128 100644 --- a/src/StdMeshers/StdMeshers_ViscousLayers.cxx +++ b/src/StdMeshers/StdMeshers_ViscousLayers.cxx @@ -3038,6 +3038,7 @@ void _ViscousBuilder::limitStepSizeByCurvature( _SolidData& data ) cnvFace._face = F; cnvFace._normalsFixed = false; cnvFace._isTooCurved = false; + cnvFace._normalsFixedOnBorders = false; double maxCurvature = cnvFace.GetMaxCurvature( data, eof, surfProp, helper ); if ( maxCurvature > 0 ) @@ -6565,6 +6566,7 @@ void _Smoother1D::prepare(_SolidData& data) _edgeDir[1] = getEdgeDir( E, leOnV[1]->_nodes[0], data.GetHelper() ); _leOnV[0]._cosin = Abs( leOnV[0]->_cosin ); _leOnV[1]._cosin = Abs( leOnV[1]->_cosin ); + _leOnV[0]._flags = _leOnV[1]._flags = 0; if ( _eos._sWOL.IsNull() ) // 3D for ( int iEnd = 0; iEnd < 2; ++iEnd ) _leOnV[iEnd]._cosin = Abs( _edgeDir[iEnd].Normalized() * leOnV[iEnd]->_normal ); @@ -11795,6 +11797,17 @@ 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 ( uvPtVec[ 0 ].node == uvPtVec.back().node && // closed + helper.IsSeamShape( uvPtVec[ 0 ].node->GetShapeID() )) + { + uvPtVec[ 0 ].SetUV( helper.GetNodeUV( F, + edges[0]->_nodes.back(), + edges[1]->_nodes.back() )); + size_t i = edges.size() - 1; + uvPtVec[ i ].SetUV( helper.GetNodeUV( F, + edges[i ]->_nodes.back(), + edges[i-1]->_nodes.back() )); + } // if ( edges.empty() ) // continue; BRep_Tool::Range( E, uvPtVec[0].param, uvPtVec.back().param ); @@ -11811,8 +11824,12 @@ bool _ViscousBuilder::shrink(_SolidData& theData) smDS->Clear(); // compute the mesh on the FACE + TopTools_IndexedMapOfShape allowed(1); + allowed.Add( sm->GetSubShape() ); + sm->SetAllowedSubShapes( &allowed ); sm->ComputeStateEngine( SMESH_subMesh::CHECK_COMPUTE_STATE ); sm->ComputeStateEngine( SMESH_subMesh::COMPUTE_SUBMESH ); + sm->SetAllowedSubShapes( nullptr ); // re-fill proxy sub-meshes of the FACE for ( size_t i = 0 ; i < _sdVec.size(); ++i ) @@ -12413,17 +12430,16 @@ gp_XY _SmoothNode::computeAngularPos(vector& uv, edgeSize.back() = edgeSize.front(); gp_XY newPos(0,0); - //int nbEdges = 0; - double sumSize = 0; + double sumWgt = 0; for ( size_t i = 1; i < edgeDir.size(); ++i ) { - if ( edgeDir[i-1].X() > 1. ) continue; - int i1 = i-1; + const int i1 = i-1; + if ( edgeDir[i1].X() > 1. ) continue; while ( edgeDir[i].X() > 1. && ++i < edgeDir.size() ); if ( i == edgeDir.size() ) break; gp_XY p = uv[i]; gp_XY norm1( -edgeDir[i1].Y(), edgeDir[i1].X() ); - gp_XY norm2( -edgeDir[i].Y(), edgeDir[i].X() ); + gp_XY norm2( -edgeDir[i ].Y(), edgeDir[i ].X() ); gp_XY bisec = norm1 + norm2; double bisecSize = bisec.Modulus(); if ( bisecSize < numeric_limits::min() ) @@ -12433,16 +12449,16 @@ gp_XY _SmoothNode::computeAngularPos(vector& uv, } bisec /= bisecSize; - gp_XY dirToN = uvToFix - p; - double distToN = dirToN.Modulus(); + gp_XY dirToN = uvToFix - p; + double distToN = bisec * dirToN; if ( bisec * dirToN < 0 ) distToN = -distToN; - newPos += ( p + bisec * distToN ) * ( edgeSize[i1] + edgeSize[i] ); - //++nbEdges; - sumSize += edgeSize[i1] + edgeSize[i]; + double wgt = edgeSize[i1] + edgeSize[i]; + newPos += ( p + bisec * distToN ) * wgt; + sumWgt += wgt; } - newPos /= /*nbEdges * */sumSize; + newPos /= sumWgt; return newPos; } diff --git a/src/Tools/MGCleanerPlug/MGCleanerMonPlugDialog.py b/src/Tools/MGCleanerPlug/MGCleanerMonPlugDialog.py index c701b3449..f5c226b87 100644 --- a/src/Tools/MGCleanerPlug/MGCleanerMonPlugDialog.py +++ b/src/Tools/MGCleanerPlug/MGCleanerMonPlugDialog.py @@ -525,18 +525,6 @@ class MGCleanerMonPlugDialog(Ui_MGCleanerPlugDialog,QWidget): def PrepareLigneCommande(self): """ - #use doc examples of mg-cleaner: - ls -al /data/tmplgls/salome/prerequis/install/COMMON_64/MeshGems-1.0/bin - source /data/tmplgls/salome/prerequis/install/LICENSE/dlim8.var.sh - export PATH=/data/tmplgls/salome/prerequis/install/COMMON_64/MeshGems-1.0/bin/Linux_64:$PATH - cp -r /data/tmplgls/salome/prerequis/install/COMMON_64/MeshGems-1.0/examples . - cd examples - mg-cleaner.exe --help - mg-cleaner.exe --in case7.mesh --out case7-test.mesh --check - mg-cleaner.exe case7.mesh case7-fix.mesh --fix - mg-cleaner.exe --in Porsche.mesh --out Porsche-test.mesh --check - mg-cleaner.exe --in Porsche.mesh --out Porschefix.mesh --fix - mg-cleaner.exe --in Porsche.mesh --out PorscheNewfix.mesh --fix --resolution_length 0.03 """ #self.commande="mg-cleaner.exe --in " + self.fichierIn + " --out " + self.fichierOut + " --fix2pass" @@ -577,6 +565,11 @@ class MGCleanerMonPlugDialog(Ui_MGCleanerPlugDialog,QWidget): if not self.CB_ComputedOverlapDistance.isChecked(): #computed default self.commande+=" --overlap_distance " + self.SP_toStr(self.SP_OverlapDistance) self.commande+=" --overlap_angle " + str(self.SP_OverlapAngle.value()) + + import SMeshHelper + key = SMeshHelper.GetMGLicenseKey( self.fichierIn ) + self.commande+=' --key ' + key + if verbose: print(("INFO: MGCCleaner command:\n %s" % self.commande)) return True diff --git a/src/Tools/MGCleanerPlug/MGCleanerMonViewText.py b/src/Tools/MGCleanerPlug/MGCleanerMonViewText.py index 5df87ad6a..a117ed2e9 100644 --- a/src/Tools/MGCleanerPlug/MGCleanerMonViewText.py +++ b/src/Tools/MGCleanerPlug/MGCleanerMonViewText.py @@ -35,11 +35,6 @@ from MGCleanerViewText_ui import Ui_ViewExe verbose = True -force = os.getenv("FORCE_DISTENE_LICENSE_FILE") -if force != None: - os.environ["DISTENE_LICENSE_FILE"] = force - os.environ["DLIM8VAR"] = "NOTHING" - class MGCleanerMonViewText(Ui_ViewExe, QDialog): """ Classe permettant la visualisation de texte diff --git a/src/Tools/MGCleanerPlug/MGCleanerplug_plugin.py b/src/Tools/MGCleanerPlug/MGCleanerplug_plugin.py index 1058e658c..7bc19e021 100644 --- a/src/Tools/MGCleanerPlug/MGCleanerplug_plugin.py +++ b/src/Tools/MGCleanerPlug/MGCleanerplug_plugin.py @@ -31,15 +31,6 @@ def MGCleanerLct(context): import tempfile from qtsalome import QFileDialog, QMessageBox - #prior test to avoid unnecessary user GUI work with ending crash - try : - os.environ['DISTENE_LICENSE_FILE'] - except: - QMessageBox.warning(None, "Products", """\ -Distene's product MeshGem Cleaner is not installed. -required environment variable: -DISTENE_LICENSE_FILE='.../dlim8.var.sh'""") - return import MGCleanerMonPlugDialog window = MGCleanerMonPlugDialog.getDialog() window.show() diff --git a/src/Tools/YamsPlug/monViewText.py b/src/Tools/YamsPlug/monViewText.py index eb371b0f1..082c9fa01 100644 --- a/src/Tools/YamsPlug/monViewText.py +++ b/src/Tools/YamsPlug/monViewText.py @@ -34,11 +34,6 @@ from ViewText_ui import Ui_ViewExe verbose = True -force = os.getenv("FORCE_DISTENE_LICENSE_FILE") -if force != None: - os.environ["DISTENE_LICENSE_FILE"] = force - os.environ["DLIM8VAR"] = "NOTHING" - class MonViewText(Ui_ViewExe, QDialog): """ Classe permettant la visualisation de texte diff --git a/src/Tools/YamsPlug/monYamsPlugDialog.py b/src/Tools/YamsPlug/monYamsPlugDialog.py index 63efd6c2d..477a2b4e4 100644 --- a/src/Tools/YamsPlug/monYamsPlugDialog.py +++ b/src/Tools/YamsPlug/monYamsPlugDialog.py @@ -545,6 +545,10 @@ class MonYamsPlugDialog(Ui_YamsPlugDialog,QWidget): self.commande+=' --in "' + self.fichierIn +'"' self.commande+=' --out "' + self.fichierOut +'"' + + import SMeshHelper + key = SMeshHelper.GetMGLicenseKey( self.fichierIn ) + self.commande+=' --key ' + key print(self.commande) return True diff --git a/src/Tools/YamsPlug/yamsplug_plugin.py b/src/Tools/YamsPlug/yamsplug_plugin.py index 278406503..4a0b005fb 100644 --- a/src/Tools/YamsPlug/yamsplug_plugin.py +++ b/src/Tools/YamsPlug/yamsplug_plugin.py @@ -31,15 +31,6 @@ def YamsLct(context): import tempfile from qtsalome import QFileDialog, QMessageBox - #prior test to avoid unnecessary user GUI work with ending crash - try : - os.environ['DISTENE_LICENSE_FILE'] - except: - QMessageBox.warning(None,"Products","""\ -Distene's product MeshGem SurfOpt is not installed. -required environment variable: -DISTENE_LICENSE_FILE='.../dlim8.var.sh'""") - return import monYamsPlugDialog window = monYamsPlugDialog.getDialog() window.show() diff --git a/src/Tools/blocFissure/CasTests/blocFissureTest.py b/src/Tools/blocFissure/CasTests/blocFissureTest.py old mode 100644 new mode 100755 index 6beab0aed..8c2d51f45 --- a/src/Tools/blocFissure/CasTests/blocFissureTest.py +++ b/src/Tools/blocFissure/CasTests/blocFissureTest.py @@ -47,7 +47,7 @@ from blocFissure.gmu import initLog from blocFissure.gmu.casStandard import casStandard # ----------------------------------------------------------------------------------------------- -LOGFILE = os.path.join(tempfile.gettempdir(),"blocFissure.log") +LOGFILE = tempfile.NamedTemporaryFile().name + "_blocFissure.log" #initLog.setDebug(LOGFILE) # debug = 10 #initLog.setVerbose(LOGFILE) # info = 20 #initLog.setRelease(LOGFILE) # warning = 30 @@ -429,7 +429,7 @@ Le(s) numéro/nom du/des tests à passer. Si aucun n'est donné, tous les cas so else: nom = cas.nomProbleme texte_a = "\n=== Exécution du cas n° {}, '{}'".format(NREF_PB[nom],nom) - logging.critical(ligne+texte_a) + logging.critical((ligne+texte_a).encode('utf-8')) try: ok_maillage = cas.executeProbleme() @@ -470,8 +470,8 @@ Le(s) numéro/nom du/des tests à passer. Si aucun n'est donné, tous les cas so texte += ". Nombre de cas_tests NOOK : {}\n".format(nb_cas_nook) else: texte += "Les {} tests se sont bien passés.\n".format(nb_cas) - print (texte+ligne) - logging.critical(ligne+texte) + print ((texte+ligne).encode('utf-8')) + logging.critical((ligne+texte).encode('utf-8')) return texte diff --git a/src/Tools/blocFissure/CasTests/ellipse_2.py b/src/Tools/blocFissure/CasTests/ellipse_2.py index aaf78dc8a..2180003f0 100644 --- a/src/Tools/blocFissure/CasTests/ellipse_2.py +++ b/src/Tools/blocFissure/CasTests/ellipse_2.py @@ -58,13 +58,27 @@ class ellipse_2(ellipse_1): # --------------------------------------------------------------------------- def setReferencesMaillageFissure(self): - self.referencesMaillageFissure = dict( \ - Entity_Quad_Quadrangle = 1748, \ - Entity_Quad_Hexa = 3795, \ - Entity_Node = 22219, \ - Entity_Quad_Edge = 258, \ - Entity_Quad_Triangle = 434, \ - Entity_Quad_Tetra = 2574, \ - Entity_Quad_Pyramid = 199, \ - Entity_Quad_Penta = 120 \ - ) + from salome.smesh import smeshBuilder + if smeshBuilder.NETGEN_VERSION_MAJOR < 6: + self.referencesMaillageFissure = dict( \ + Entity_Quad_Quadrangle = 1748, \ + Entity_Quad_Hexa = 3795, \ + Entity_Node = 22219, \ + Entity_Quad_Edge = 258, \ + Entity_Quad_Triangle = 434, \ + Entity_Quad_Tetra = 2574, \ + Entity_Quad_Pyramid = 199, \ + Entity_Quad_Penta = 120 \ + ) + else: + self.referencesMaillageFissure = dict( \ + Entity_Quad_Quadrangle = 1748, \ + Entity_Quad_Hexa = 3795, \ + Entity_Node = 22022, \ + Entity_Quad_Edge = 258, \ + Entity_Quad_Triangle = 412, \ + Entity_Quad_Tetra = 2442, \ + Entity_Quad_Pyramid = 199, \ + Entity_Quad_Penta = 120 \ + ) + diff --git a/src/Tools/blocFissure/CasTests/faceGauche.py b/src/Tools/blocFissure/CasTests/faceGauche.py index b04c9a551..d1bf2f644 100644 --- a/src/Tools/blocFissure/CasTests/faceGauche.py +++ b/src/Tools/blocFissure/CasTests/faceGauche.py @@ -113,13 +113,26 @@ class faceGauche(fissureGenerique): # --------------------------------------------------------------------------- def setReferencesMaillageFissure(self): - self.referencesMaillageFissure = dict( \ - Entity_Quad_Edge = 750, \ - Entity_Quad_Quadrangle = 4177, \ - Entity_Quad_Hexa = 6224, \ - Entity_Node = 81588, \ - Entity_Quad_Triangle = 2298, \ - Entity_Quad_Tetra = 33764, \ - Entity_Quad_Pyramid = 1236, \ - Entity_Quad_Penta = 936 \ - ) + from salome.smesh import smeshBuilder + if smeshBuilder.NETGEN_VERSION_MAJOR < 6: + self.referencesMaillageFissure = dict( \ + Entity_Quad_Edge = 750, \ + Entity_Quad_Quadrangle = 4177, \ + Entity_Quad_Hexa = 6224, \ + Entity_Node = 81588, \ + Entity_Quad_Triangle = 2298, \ + Entity_Quad_Tetra = 33764, \ + Entity_Quad_Pyramid = 1236, \ + Entity_Quad_Penta = 936 \ + ) + else: + self.referencesMaillageFissure = dict( \ + Entity_Quad_Quadrangle = 4177, \ + Entity_Quad_Hexa = 6224, \ + Entity_Node = 83887, \ + Entity_Quad_Edge = 750, \ + Entity_Quad_Triangle = 2434, \ + Entity_Quad_Tetra = 35375, \ + Entity_Quad_Pyramid = 1236, \ + Entity_Quad_Penta = 936 \ + ) diff --git a/src/Tools/blocFissure/CasTests/fissureCoude_10.py b/src/Tools/blocFissure/CasTests/fissureCoude_10.py index e9a83799d..51160ffff 100644 --- a/src/Tools/blocFissure/CasTests/fissureCoude_10.py +++ b/src/Tools/blocFissure/CasTests/fissureCoude_10.py @@ -107,13 +107,26 @@ class fissureCoude_10(fissureCoude): # --------------------------------------------------------------------------- def setReferencesMaillageFissure(self): - self.referencesMaillageFissure = dict ( \ - Entity_Quad_Quadrangle = 6160, \ - Entity_Quad_Hexa = 5864, \ - Entity_Node = 78012, \ - Entity_Quad_Edge = 1346, \ - Entity_Quad_Triangle = 9022, \ - Entity_Quad_Tetra = 24341, \ - Entity_Quad_Pyramid = 1232, \ - Entity_Quad_Penta = 1136 \ - ) + from salome.smesh import smeshBuilder + if smeshBuilder.NETGEN_VERSION_MAJOR < 6: + self.referencesMaillageFissure = dict ( \ + Entity_Quad_Quadrangle = 6160, \ + Entity_Quad_Hexa = 5864, \ + Entity_Node = 78012, \ + Entity_Quad_Edge = 1346, \ + Entity_Quad_Triangle = 9022, \ + Entity_Quad_Tetra = 24341, \ + Entity_Quad_Pyramid = 1232, \ + Entity_Quad_Penta = 1136 \ + ) + else: + self.referencesMaillageFissure = dict ( \ + Entity_Quad_Quadrangle = 6160, \ + Entity_Quad_Hexa = 5864, \ + Entity_Node = 80605, \ + Entity_Quad_Edge = 1345, \ + Entity_Quad_Triangle = 9726, \ + Entity_Quad_Tetra = 25690, \ + Entity_Quad_Pyramid = 1232, \ + Entity_Quad_Penta = 1136 \ + ) diff --git a/src/Tools/blocFissure/CasTests/fissureCoude_2.py b/src/Tools/blocFissure/CasTests/fissureCoude_2.py index 8b981329b..24bd03b2e 100644 --- a/src/Tools/blocFissure/CasTests/fissureCoude_2.py +++ b/src/Tools/blocFissure/CasTests/fissureCoude_2.py @@ -105,13 +105,26 @@ class fissureCoude_2(fissureCoude): # --------------------------------------------------------------------------- def setReferencesMaillageFissure(self): - self.referencesMaillageFissure = dict( \ - Entity_Quad_Quadrangle = 7828, \ - Entity_Quad_Hexa = 10437, \ - Entity_Node = 101695, \ - Entity_Quad_Edge = 1199, \ - Entity_Quad_Triangle = 4230, \ - Entity_Quad_Tetra = 30013, \ - Entity_Quad_Pyramid = 1428, \ - Entity_Quad_Penta = 1344 \ - ) + from salome.smesh import smeshBuilder + if smeshBuilder.NETGEN_VERSION_MAJOR < 6: + self.referencesMaillageFissure = dict( \ + Entity_Quad_Quadrangle = 7828, \ + Entity_Quad_Hexa = 10437, \ + Entity_Node = 101695, \ + Entity_Quad_Edge = 1199, \ + Entity_Quad_Triangle = 4230, \ + Entity_Quad_Tetra = 30013, \ + Entity_Quad_Pyramid = 1428, \ + Entity_Quad_Penta = 1344 \ + ) + else: + self.referencesMaillageFissure = dict( \ + Entity_Quad_Quadrangle = 7828, \ + Entity_Quad_Hexa = 10437, \ + Entity_Node = 106391, \ + Entity_Quad_Edge = 1199, \ + Entity_Quad_Triangle = 4702, \ + Entity_Quad_Tetra = 33175, \ + Entity_Quad_Pyramid = 1428, \ + Entity_Quad_Penta = 1344 \ + ) diff --git a/src/Tools/blocFissure/CasTests/fissureCoude_5.py b/src/Tools/blocFissure/CasTests/fissureCoude_5.py index 5874a54dd..5d53ee6e9 100644 --- a/src/Tools/blocFissure/CasTests/fissureCoude_5.py +++ b/src/Tools/blocFissure/CasTests/fissureCoude_5.py @@ -105,13 +105,26 @@ class fissureCoude_5(fissureCoude): # --------------------------------------------------------------------------- def setReferencesMaillageFissure(self): - self.referencesMaillageFissure = dict( \ - Entity_Quad_Quadrangle = 5366, \ - Entity_Quad_Hexa = 7120, \ - Entity_Node = 54832, \ - Entity_Quad_Edge = 722, \ - Entity_Quad_Triangle = 1570, \ - Entity_Quad_Tetra = 11747, \ - Entity_Quad_Pyramid = 532, \ - Entity_Quad_Penta = 496 \ - ) + from salome.smesh import smeshBuilder + if smeshBuilder.NETGEN_VERSION_MAJOR < 6: + self.referencesMaillageFissure = dict( \ + Entity_Quad_Quadrangle = 5366, \ + Entity_Quad_Hexa = 7120, \ + Entity_Node = 54832, \ + Entity_Quad_Edge = 722, \ + Entity_Quad_Triangle = 1570, \ + Entity_Quad_Tetra = 11747, \ + Entity_Quad_Pyramid = 532, \ + Entity_Quad_Penta = 496 \ + ) + else: + self.referencesMaillageFissure = dict( \ + Entity_Quad_Quadrangle = 5366, \ + Entity_Quad_Hexa = 7120, \ + Entity_Node = 54175, \ + Entity_Quad_Edge = 721, \ + Entity_Quad_Triangle = 1482, \ + Entity_Quad_Tetra = 11324, \ + Entity_Quad_Pyramid = 532, \ + Entity_Quad_Penta = 496 \ + ) diff --git a/src/Tools/blocFissure/CasTests/fissureCoude_6.py b/src/Tools/blocFissure/CasTests/fissureCoude_6.py index 394e29aee..646e647c0 100644 --- a/src/Tools/blocFissure/CasTests/fissureCoude_6.py +++ b/src/Tools/blocFissure/CasTests/fissureCoude_6.py @@ -106,13 +106,26 @@ class fissureCoude_6(fissureCoude): # --------------------------------------------------------------------------- def setReferencesMaillageFissure(self): - self.referencesMaillageFissure = dict( \ - Entity_Quad_Quadrangle = 7392, \ - Entity_Quad_Hexa = 9888, \ - Entity_Node = 62571, \ - Entity_Quad_Edge = 833, \ - Entity_Quad_Triangle = 1048, \ - Entity_Quad_Tetra = 7723, \ - Entity_Quad_Pyramid = 452, \ - Entity_Quad_Penta = 408 \ - ) + from salome.smesh import smeshBuilder + if smeshBuilder.NETGEN_VERSION_MAJOR < 6: + self.referencesMaillageFissure = dict( \ + Entity_Quad_Quadrangle = 7392, \ + Entity_Quad_Hexa = 9888, \ + Entity_Node = 62571, \ + Entity_Quad_Edge = 833, \ + Entity_Quad_Triangle = 1048, \ + Entity_Quad_Tetra = 7723, \ + Entity_Quad_Pyramid = 452, \ + Entity_Quad_Penta = 408 \ + ) + else: + self.referencesMaillageFissure = dict( \ + Entity_Quad_Quadrangle = 7392, \ + Entity_Quad_Hexa = 9888, \ + Entity_Node = 62361, \ + Entity_Quad_Edge = 833, \ + Entity_Quad_Triangle = 983, \ + Entity_Quad_Tetra = 7642, \ + Entity_Quad_Pyramid = 452, \ + Entity_Quad_Penta = 408 \ + ) diff --git a/src/Tools/blocFissure/CasTests/fissureCoude_7.py b/src/Tools/blocFissure/CasTests/fissureCoude_7.py index f9e261752..5601392a0 100644 --- a/src/Tools/blocFissure/CasTests/fissureCoude_7.py +++ b/src/Tools/blocFissure/CasTests/fissureCoude_7.py @@ -107,13 +107,26 @@ class fissureCoude_7(fissureCoude): # --------------------------------------------------------------------------- def setReferencesMaillageFissure(self): - self.referencesMaillageFissure = dict( \ - Entity_Quad_Quadrangle = 7758, \ - Entity_Quad_Hexa = 10696, \ - Entity_Node = 71535, \ - Entity_Quad_Edge = 882, \ - Entity_Quad_Triangle = 1378, \ - Entity_Quad_Tetra = 10847, \ - Entity_Quad_Pyramid = 668, \ - Entity_Quad_Penta = 612 \ - ) + from salome.smesh import smeshBuilder + if smeshBuilder.NETGEN_VERSION_MAJOR < 6: + self.referencesMaillageFissure = dict( \ + Entity_Quad_Quadrangle = 7758, \ + Entity_Quad_Hexa = 10696, \ + Entity_Node = 71535, \ + Entity_Quad_Edge = 882, \ + Entity_Quad_Triangle = 1378, \ + Entity_Quad_Tetra = 10847, \ + Entity_Quad_Pyramid = 668, \ + Entity_Quad_Penta = 612 \ + ) + else: + self.referencesMaillageFissure = dict( \ + Entity_Quad_Quadrangle = 7758, \ + Entity_Quad_Hexa = 10696, \ + Entity_Node = 70936, \ + Entity_Quad_Edge = 881, \ + Entity_Quad_Triangle = 1300, \ + Entity_Quad_Tetra = 10449, \ + Entity_Quad_Pyramid = 668, \ + Entity_Quad_Penta = 612 \ + ) diff --git a/src/Tools/blocFissure/CasTests/fissureCoude_8.py b/src/Tools/blocFissure/CasTests/fissureCoude_8.py index 490762022..502b3b0b7 100644 --- a/src/Tools/blocFissure/CasTests/fissureCoude_8.py +++ b/src/Tools/blocFissure/CasTests/fissureCoude_8.py @@ -107,13 +107,26 @@ class fissureCoude_8(fissureCoude): # --------------------------------------------------------------------------- def setReferencesMaillageFissure(self): - self.referencesMaillageFissure = dict( \ - Entity_Quad_Quadrangle = 4572, \ - Entity_Quad_Hexa = 5128, \ - Entity_Node = 45641, \ - Entity_Quad_Edge = 648, \ - Entity_Quad_Triangle = 1282, \ - Entity_Quad_Tetra = 11122, \ - Entity_Quad_Pyramid = 768, \ - Entity_Quad_Penta = 752 \ - ) + from salome.smesh import smeshBuilder + if smeshBuilder.NETGEN_VERSION_MAJOR < 6: + self.referencesMaillageFissure = dict( \ + Entity_Quad_Quadrangle = 4572, \ + Entity_Quad_Hexa = 5128, \ + Entity_Node = 45641, \ + Entity_Quad_Edge = 648, \ + Entity_Quad_Triangle = 1282, \ + Entity_Quad_Tetra = 11122, \ + Entity_Quad_Pyramid = 768, \ + Entity_Quad_Penta = 752 \ + ) + else: + self.referencesMaillageFissure = dict( \ + Entity_Quad_Quadrangle = 4572, \ + Entity_Quad_Hexa = 5128, \ + Entity_Node = 46393, \ + Entity_Quad_Edge = 648, \ + Entity_Quad_Triangle = 1286, \ + Entity_Quad_Tetra = 11686, \ + Entity_Quad_Pyramid = 768, \ + Entity_Quad_Penta = 752 \ + ) diff --git a/src/Tools/blocFissure/CasTests/fissureCoude_9.py b/src/Tools/blocFissure/CasTests/fissureCoude_9.py index 79485fcbf..cfd205ece 100644 --- a/src/Tools/blocFissure/CasTests/fissureCoude_9.py +++ b/src/Tools/blocFissure/CasTests/fissureCoude_9.py @@ -105,13 +105,26 @@ class fissureCoude_9(fissureCoude): # --------------------------------------------------------------------------- def setReferencesMaillageFissure(self): - self.referencesMaillageFissure = dict( \ - Entity_Quad_Quadrangle = 14864, \ - Entity_Quad_Hexa = 26772, \ - Entity_Node = 156163, \ - Entity_Quad_Edge = 1237, \ - Entity_Quad_Triangle = 3178, \ - Entity_Quad_Tetra = 16952, \ - Entity_Quad_Pyramid = 916, \ - Entity_Quad_Penta = 780 \ - ) + from salome.smesh import smeshBuilder + if smeshBuilder.NETGEN_VERSION_MAJOR < 6: + self.referencesMaillageFissure = dict( \ + Entity_Quad_Quadrangle = 14864, \ + Entity_Quad_Hexa = 26772, \ + Entity_Node = 156163, \ + Entity_Quad_Edge = 1237, \ + Entity_Quad_Triangle = 3178, \ + Entity_Quad_Tetra = 16952, \ + Entity_Quad_Pyramid = 916, \ + Entity_Quad_Penta = 780 \ + ) + else: + self.referencesMaillageFissure = dict( \ + Entity_Quad_Quadrangle = 14864, \ + Entity_Quad_Hexa = 26772, \ + Entity_Node = 157045, \ + Entity_Quad_Edge = 1237, \ + Entity_Quad_Triangle = 3338, \ + Entity_Quad_Tetra = 17484, \ + Entity_Quad_Pyramid = 916, \ + Entity_Quad_Penta = 780 \ + ) diff --git a/src/Tools/blocFissure/CasTests/fissure_Coude.py b/src/Tools/blocFissure/CasTests/fissure_Coude.py index 71dadf336..afd31061d 100644 --- a/src/Tools/blocFissure/CasTests/fissure_Coude.py +++ b/src/Tools/blocFissure/CasTests/fissure_Coude.py @@ -517,13 +517,26 @@ class fissure_Coude(fissureGenerique): # --------------------------------------------------------------------------- def setReferencesMaillageFissure(self): - self.referencesMaillageFissure = dict( \ - Entity_Quad_Quadrangle = 6710, \ - Entity_Quad_Hexa = 8656, \ - Entity_Node = 76807, \ - Entity_Quad_Edge = 1006, \ - Entity_Quad_Triangle = 2342, \ - Entity_Quad_Tetra = 20392, \ - Entity_Quad_Pyramid = 1232, \ - Entity_Quad_Penta = 1176 \ - ) + from salome.smesh import smeshBuilder + if smeshBuilder.NETGEN_VERSION_MAJOR < 6: + self.referencesMaillageFissure = dict( \ + Entity_Quad_Quadrangle = 6710, \ + Entity_Quad_Hexa = 8656, \ + Entity_Node = 76807, \ + Entity_Quad_Edge = 1006, \ + Entity_Quad_Triangle = 2342, \ + Entity_Quad_Tetra = 20392, \ + Entity_Quad_Pyramid = 1232, \ + Entity_Quad_Penta = 1176 \ + ) + else: + self.referencesMaillageFissure = dict( \ + Entity_Quad_Quadrangle = 6710, \ + Entity_Quad_Hexa = 8656, \ + Entity_Node = 77391, \ + Entity_Quad_Edge = 1006, \ + Entity_Quad_Triangle = 2496, \ + Entity_Quad_Tetra = 20711, \ + Entity_Quad_Pyramid = 1232, \ + Entity_Quad_Penta = 1176 \ + ) diff --git a/src/Tools/blocFissure/doc/testcases.rst b/src/Tools/blocFissure/doc/testcases.rst index 57dc09481..45eb7809d 100644 --- a/src/Tools/blocFissure/doc/testcases.rst +++ b/src/Tools/blocFissure/doc/testcases.rst @@ -95,7 +95,7 @@ All 16 cases are shown Table 2. Two views show the whole cracked structure and a | vis (Crack is in the radius filet between the screw head and the screw shank) | +--------------------------------------------+-----------------------------------------------+ |.. image:: images/13_vis_1.png | .. image:: images/13_vis_1_2.png | -| :width: 400 | :width: 400 | +| :width: 400 | :width: 400 | | :align: center | :align: center | +--------------------------------------------+-----------------------------------------------+ | tube | diff --git a/src/Tools/blocFissure/gmu/getStatsMaillageFissure.py b/src/Tools/blocFissure/gmu/getStatsMaillageFissure.py old mode 100644 new mode 100755 index 2f1a6813d..3943e374d --- a/src/Tools/blocFissure/gmu/getStatsMaillageFissure.py +++ b/src/Tools/blocFissure/gmu/getStatsMaillageFissure.py @@ -48,7 +48,7 @@ def getStatsMaillageFissure(maillage, referencesMaillageFissure, maillageFissure text_2 = "" ok_maillage = True - with open(fichierStatMaillageFissure, "w") as fic_stat : + with open(fichierStatMaillageFissure, "w", encoding='utf-8') as fic_stat : # Le nombre de quadrangles ou d'hexaèdres doit être rigoureusement identique for key in ('Entity_Quad_Quadrangle', 'Entity_Quad_Hexa'): @@ -89,6 +89,6 @@ def getStatsMaillageFissure(maillage, referencesMaillageFissure, maillageFissure with open(fichierNewRef, "w") as fic_info : fic_info.write(text_2[:-4]+" \\") - print (text) + print (text.encode('utf-8')) return ok_maillage diff --git a/src/Tools/blocFissure/gmu/initLog.py b/src/Tools/blocFissure/gmu/initLog.py index ee9d1863d..c665e5c75 100644 --- a/src/Tools/blocFissure/gmu/initLog.py +++ b/src/Tools/blocFissure/gmu/initLog.py @@ -30,7 +30,7 @@ error = 40 critical = 50 always = 100 -LOGFILE = os.path.join(tempfile.gettempdir(),"blocFissure.log") +LOGFILE = tempfile.NamedTemporaryFile().name + "_blocFissure.log" LOG_LEVEL = warning diff --git a/src/Tools/padder/meshjob/impl/CMakeLists.txt b/src/Tools/padder/meshjob/impl/CMakeLists.txt index dedd03cb5..6e555a7a4 100644 --- a/src/Tools/padder/meshjob/impl/CMakeLists.txt +++ b/src/Tools/padder/meshjob/impl/CMakeLists.txt @@ -17,9 +17,11 @@ # See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com # +include(${SWIG_USE_FILE}) + # --- options --- -# additional include directories INCLUDE_DIRECTORIES( + ${CMAKE_CURRENT_SOURCE_DIR} ${KERNEL_INCLUDE_DIRS} ${GEOM_INCLUDE_DIRS} ${OpenCASCADE_INCLUDE_DIR} @@ -86,6 +88,28 @@ SET(SPADDERPluginTesterEngine_SOURCES SPADDERPluginTester_i.cxx ) +# - swiggy pop + +SET(SMeshPadderHelper_HEADERS SMeshPadderHelper.h SMeshPadderHelper.i) +SET(SMeshPadderHelper_SOURCES SMeshPadderHelper.cxx ${SMeshPadderHelper_HEADERS}) +SET_SOURCE_FILES_PROPERTIES(SMeshPadderHelper.i PROPERTIES CPLUSPLUS ON) +SET_SOURCE_FILES_PROPERTIES(SMeshPadderHelper.i PROPERTIES SWIG_FLAGS "-py3") +SET_SOURCE_FILES_PROPERTIES(SMeshPadderHelper_wrap.cpp PROPERTIES COMPILE_FLAGS "-DHAVE_CONFIG_H") +SET(_swig_SCRIPTS ${CMAKE_CURRENT_BINARY_DIR}/SMeshPadderHelper.py ) +IF(${CMAKE_VERSION} VERSION_LESS "3.8.0") + SWIG_ADD_MODULE(SMeshPadderHelper python ${SMeshPadderHelper_SOURCES}) +ELSE() + SWIG_ADD_LIBRARY(SMeshPadderHelper LANGUAGE python SOURCES ${SMeshPadderHelper_SOURCES}) +ENDIF() +SWIG_LINK_LIBRARIES(SMeshPadderHelper ${PYTHON_LIBRARIES} ${PLATFORM_LIBS} MeshJobManagerEngine ) +SWIG_CHECK_GENERATION(SMeshPadderHelper) +IF(WIN32) + SET_TARGET_PROPERTIES(_SMeshPadderHelper PROPERTIES DEBUG_OUTPUT_NAME _SMeshPadderHelper_d) +ENDIF(WIN32) +install(TARGETS _SMeshPadderHelper DESTINATION ${SALOME_INSTALL_LIBS}) +install(FILES ${SMeshPadderHelper_HEADERS} DESTINATION ${SALOME_INSTALL_HEADERS}) +SALOME_INSTALL_SCRIPTS("${_swig_SCRIPTS}" ${SALOME_INSTALL_BINS} EXTRA_DPYS "${SWIG_MODULE_SMeshPadderHelper_REAL_NAME}") + # --- rules --- ADD_LIBRARY(MeshJobManagerEngine ${MeshJobManagerEngine_SOURCES}) diff --git a/src/Tools/padder/meshjob/impl/MeshJobManager_i.cxx b/src/Tools/padder/meshjob/impl/MeshJobManager_i.cxx index a8b0295a8..10bae23e7 100644 --- a/src/Tools/padder/meshjob/impl/MeshJobManager_i.cxx +++ b/src/Tools/padder/meshjob/impl/MeshJobManager_i.cxx @@ -83,6 +83,11 @@ static bool fexists(const char *filename) return false; } +Engines::EngineComponent_var RetrievePadderMeshJobManagerInstance() +{ + +} + // // ==================================================================== // Constructor/Destructor @@ -92,8 +97,9 @@ MeshJobManager_i::MeshJobManager_i(CORBA::ORB_ptr orb, PortableServer::POA_ptr poa, PortableServer::ObjectId * contId, const char *instanceName, - const char *interfaceName) - : Engines_Component_i(orb, poa, contId, instanceName, interfaceName) + const char *interfaceName, + bool checkNS, bool regist) + : Engines_Component_i(orb, poa, contId, instanceName, interfaceName, checkNS, regist) { LOG("Activating MESHJOB::MeshJobManager object"); _thisObj = this ; diff --git a/src/Tools/padder/meshjob/impl/MeshJobManager_i.hxx b/src/Tools/padder/meshjob/impl/MeshJobManager_i.hxx index e731371ff..9c9968f10 100644 --- a/src/Tools/padder/meshjob/impl/MeshJobManager_i.hxx +++ b/src/Tools/padder/meshjob/impl/MeshJobManager_i.hxx @@ -43,6 +43,7 @@ #define MESHJOBMANAGERENGINE_EXPORT #endif +Engines::EngineComponent_var RetrievePadderMeshJobManagerInstance(); class MESHJOBMANAGERENGINE_EXPORT MeshJobManager_i: public virtual POA_MESHJOB::MeshJobManager, public Engines_Component_i @@ -50,7 +51,7 @@ class MESHJOBMANAGERENGINE_EXPORT MeshJobManager_i: public virtual POA_MESHJOB:: public: MeshJobManager_i(CORBA::ORB_ptr orb, PortableServer::POA_ptr poa, PortableServer::ObjectId * contId, - const char *instanceName, const char *interfaceName); + const char *instanceName, const char *interfaceName, bool checkNS = true, bool regist = true); ~MeshJobManager_i(); bool configure (const char *configId, diff --git a/src/Tools/padder/meshjob/impl/SMeshPadderHelper.cxx b/src/Tools/padder/meshjob/impl/SMeshPadderHelper.cxx new file mode 100644 index 000000000..cc51e5ad2 --- /dev/null +++ b/src/Tools/padder/meshjob/impl/SMeshPadderHelper.cxx @@ -0,0 +1,62 @@ +// Copyright (C) 2021 CEA/DEN, EDF R&D, OPEN CASCADE +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +#include "SMeshPadderHelper.h" + +#include "MeshJobManager_i.hxx" +#include "SALOME_Container_i.hxx" +#include "SALOME_KernelServices.hxx" + +#include "SALOME_Fake_NamingService.hxx" + +static Engines::EngineComponent_var _unique_compo; + +Engines::EngineComponent_var BuildPadderMeshJobManagerInstance() +{ + if (CORBA::is_nil(_unique_compo)) + { + CORBA::ORB_var orb; + { + int argc(0); + orb = CORBA::ORB_init(argc, nullptr); + } + CORBA::Object_var obj = orb->resolve_initial_references("RootPOA"); + PortableServer::POA_var poa = PortableServer::POA::_narrow(obj); + PortableServer::POAManager_var pman = poa->the_POAManager(); + CORBA::PolicyList policies; + policies.length(0); + auto *cont(KERNEL::getContainerSA()); + PortableServer::ObjectId *conId(cont->getCORBAId()); + // + pman->activate(); + // + MeshJobManager_i *servant = new MeshJobManager_i(orb, poa, conId, "MeshJobManager_inst_3", "MeshJobManager", false, false); + PortableServer::ObjectId *zeId = servant->getId(); + CORBA::Object_var zeRef = poa->id_to_reference(*zeId); + _unique_compo = Engines::EngineComponent::_narrow(zeRef); + } + return _unique_compo; +} + +std::string BuildPadderMeshJobManagerInstanceInternal() +{ + Engines::EngineComponent_var zeRef = BuildPadderMeshJobManagerInstance(); + CORBA::String_var ior = KERNEL::getORB()->object_to_string(zeRef); + return std::string(ior.in()); +} diff --git a/src/Tools/padder/meshjob/impl/SMeshPadderHelper.h b/src/Tools/padder/meshjob/impl/SMeshPadderHelper.h new file mode 100644 index 000000000..afd7594e7 --- /dev/null +++ b/src/Tools/padder/meshjob/impl/SMeshPadderHelper.h @@ -0,0 +1,25 @@ +// Copyright (C) 2021 CEA/DEN, EDF R&D, OPEN CASCADE +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +#pragma once + +#include + +std::string BuildPadderMeshJobManagerInstanceInternal(); + diff --git a/src/Tools/padder/meshjob/impl/SMeshPadderHelper.i b/src/Tools/padder/meshjob/impl/SMeshPadderHelper.i new file mode 100644 index 000000000..db619fceb --- /dev/null +++ b/src/Tools/padder/meshjob/impl/SMeshPadderHelper.i @@ -0,0 +1,34 @@ +// Copyright (C) 2021 CEA/DEN, EDF R&D, OPEN CASCADE +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +%module SMeshPadderHelper + +%include "std_string.i" + +%{ +#include "SMeshPadderHelper.h" +%} + +%inline +{ + std::string BuildPadderMeshJobManagerInstance() + { + return BuildPadderMeshJobManagerInstanceInternal(); + } +} diff --git a/src/Tools/padder/spadderpy/__init__.py b/src/Tools/padder/spadderpy/__init__.py index 8a1128e9b..13ec28d17 100644 --- a/src/Tools/padder/spadderpy/__init__.py +++ b/src/Tools/padder/spadderpy/__init__.py @@ -94,7 +94,7 @@ def getSpadderCatalogFilename(): def loadSpadderCatalog(): import salome salome.salome_init() - obj = salome.naming_service.Resolve('Kernel/ModulCatalog') + obj = salome.naming_service.Resolve('/Kernel/ModulCatalog') import SALOME_ModuleCatalog catalog = obj._narrow(SALOME_ModuleCatalog.ModuleCatalog) if not catalog: