diff --git a/CMakeLists.txt b/CMakeLists.txt index bc57e9425..b207ae53e 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -31,7 +31,7 @@ ENDIF(WIN32) STRING(TOUPPER ${PROJECT_NAME} PROJECT_NAME_UC) SET(${PROJECT_NAME_UC}_MAJOR_VERSION 8) -SET(${PROJECT_NAME_UC}_MINOR_VERSION 3) +SET(${PROJECT_NAME_UC}_MINOR_VERSION 4) SET(${PROJECT_NAME_UC}_PATCH_VERSION 0) SET(${PROJECT_NAME_UC}_VERSION ${${PROJECT_NAME_UC}_MAJOR_VERSION}.${${PROJECT_NAME_UC}_MINOR_VERSION}.${${PROJECT_NAME_UC}_PATCH_VERSION}) @@ -77,6 +77,11 @@ OPTION(SALOME_BUILD_DOC "Generate SALOME SMESH documentation" ON) OPTION(SALOME_BUILD_GUI "Enable GUI" ON) OPTION(SALOME_SMESH_USE_CGNS "Enable import/export to CGNS format" OFF) OPTION(SALOME_SMESH_USE_TBB "Enable parallel computation" OFF) +OPTION(SALOME_SMESH_DYNLOAD_LOCAL "Load plug-ins' symbols locally (Linux only)" ON) + +IF(SALOME_SMESH_DYNLOAD_LOCAL) + ADD_DEFINITIONS(-DDYNLOAD_LOCAL) +ENDIF(SALOME_SMESH_DYNLOAD_LOCAL) #On Linux use Fortran to compile MEFISTO2D IF(NOT WIN32) @@ -85,12 +90,12 @@ IF(NOT WIN32) ADD_DEFINITIONS(-DENABLE_MEFISTO) ENDIF(NOT WIN32) -MARK_AS_ADVANCED(SALOME_BUILD_GUI SALOME_SMESH_USE_CGNS SALOME_SMESH_USE_TBB) +MARK_AS_ADVANCED(SALOME_BUILD_GUI SALOME_SMESH_USE_CGNS SALOME_SMESH_USE_TBB SALOME_SMESH_DYNLOAD_LOCAL) # Prerequisites # ============= # Find "big" prerequisites first - they reference themselves many others -# -> this can help finding the smaller prerequisites and detect conficts. +# -> this can help finding the smaller prerequisites and detect conflicts. # In our case KERNEL has already loaded many prereq: ## diff --git a/ChangeLog b/ChangeLog index 85c700e46..7df59af50 100644 --- a/ChangeLog +++ b/ChangeLog @@ -37,7 +37,7 @@ 2004-01-05 16:14 Jerome Robert - * adm_local/unix/config_files/check_Netgen.m4: Fix a mispelled + * adm_local/unix/config_files/check_Netgen.m4: Fix a misspelled environment variable for idl python 2004-01-05 14:28 tag V1_3_1 @@ -59,7 +59,7 @@ 2004-01-05 09:05 Jerome Robert * src/: SMDS/SMDS_Mesh.cxx, SMESHDS/SMESHDS_Document.cxx: [Bug - SMESH4830] bug in instal with gcc 2.95. Bug fixed. Note: SGI say + SMESH4830] bug in install with gcc 2.95. Bug fixed. Note: SGI say that is requiered to use set_intersection (see http://www.sgi.com/tech/stl/set_intersection.html). @@ -73,7 +73,7 @@ 2003-12-15 13:15 Nadir Bouhamou * src/SMESHDS/SMESHDS_Script.cxx: correct a small bug found by the - EDF developpement team (PN and AT) : AddVolume in the case of a + EDF development team (PN and AT) : AddVolume in the case of a Tetrahedron. 2003-12-11 09:51 Jerome Robert @@ -1194,7 +1194,7 @@ * idl/Makefile.in, adm_local/unix/make_commence.in, adm_local/unix/make_omniorb.in, build_configure, - configure.in.base: NRI : Update IDL Dependancies. + configure.in.base: NRI : Update IDL Dependencies. 2003-05-28 07:20 Nicolas Rejneri diff --git a/README b/README index 78f5c9b6f..74932ecba 100644 --- a/README +++ b/README @@ -41,7 +41,7 @@ Installation Pre-requisites -------------- -SALOME platform relies on a set of third-party softwares; some of them are needed +SALOME platform relies on a set of third-party software; some of them are needed at build time only, while other ones are needed in runtime also. For more information about the pre-requisites please visit SALOME platform web diff --git a/SalomeSMESHConfig.cmake.in b/SalomeSMESHConfig.cmake.in index dbe99c27e..0012b2f6b 100644 --- a/SalomeSMESHConfig.cmake.in +++ b/SalomeSMESHConfig.cmake.in @@ -1,6 +1,6 @@ # - Config file for the @PROJECT_NAME@ package # It defines the following variables. -# Specific to the pacakge @PROJECT_NAME@ itself: +# Specific to the package @PROJECT_NAME@ itself: # @PROJECT_NAME_UC@_ROOT_DIR_EXP - the root path of the installation providing this CMake file # diff --git a/doc/salome/examples/create_penta_biquad.py b/doc/salome/examples/create_penta_biquad.py new file mode 100644 index 000000000..9e7ec271a --- /dev/null +++ b/doc/salome/examples/create_penta_biquad.py @@ -0,0 +1,42 @@ +# -*- coding: utf-8 -*- + +import sys +import salome + +salome.salome_init() + +import SMESH, SALOMEDS +from salome.smesh import smeshBuilder + +smesh = smeshBuilder.New() +unPentaBiQuad = smesh.Mesh() +nodeID = unPentaBiQuad.AddNode( 0, 0, 0 ) +nodeID = unPentaBiQuad.AddNode( 10, 0, 0 ) +nodeID = unPentaBiQuad.AddNode( 0, 10, 0 ) +nodeID = unPentaBiQuad.AddNode( 0, 0, 10 ) +nodeID = unPentaBiQuad.AddNode( 10, 0, 10 ) +nodeID = unPentaBiQuad.AddNode( 0, 10, 10 ) +nodeID = unPentaBiQuad.AddNode( 5, 0, 0 ) +nodeID = unPentaBiQuad.AddNode( 7, 7, 0 ) +nodeID = unPentaBiQuad.AddNode( 0, 5, 0 ) +nodeID = unPentaBiQuad.AddNode( 5, 0, 10 ) +nodeID = unPentaBiQuad.AddNode( 7, 7, 10 ) +nodeID = unPentaBiQuad.AddNode( 0, 5, 10 ) +nodeID = unPentaBiQuad.AddNode( 0, 0, 5 ) +nodeID = unPentaBiQuad.AddNode( 10, 0, 5 ) +nodeID = unPentaBiQuad.AddNode( 0, 10, 5 ) +nodeID = unPentaBiQuad.AddNode( 5, -1, 5 ) +nodeID = unPentaBiQuad.AddNode( 8, 8, 5 ) +nodeID = unPentaBiQuad.AddNode( -1, 5, 5 ) +volID = unPentaBiQuad.AddVolume( [ 4, 5, 6, 1, 2, 3, 10, 11, 12, 7, 8, 9, 13, 14, 15, 16, 17, 18 ] ) + +infos = unPentaBiQuad.GetMeshInfo() +print("Number of biquadratic pentahedrons:", infos[SMESH.Entity_BiQuad_Penta]) +if (infos[SMESH.Entity_BiQuad_Penta] != 1): + raise RuntimeError("Bad number of biquadratic pentahedrons: should be 1") + +## Set names of Mesh objects +smesh.SetName(unPentaBiQuad.GetMesh(), 'unPentaBiQuad') + +if salome.sg.hasDesktop(): + salome.sg.updateObjBrowser() diff --git a/doc/salome/examples/ex_MakePolyLine.py b/doc/salome/examples/ex_MakePolyLine.py new file mode 100644 index 000000000..0a9c67b1b --- /dev/null +++ b/doc/salome/examples/ex_MakePolyLine.py @@ -0,0 +1,37 @@ +import salome +salome.salome_init() + +### create geometry + +from salome.geom import geomBuilder +geompy = geomBuilder.New(salome.myStudy) + +Box_1 = geompy.MakeBoxDXDYDZ(200, 200, 200) +geompy.addToStudy( Box_1, 'Box_1' ) + +### create a mesh + +import SMESH +from salome.smesh import smeshBuilder +smesh = smeshBuilder.New(salome.myStudy) + +Mesh_1 = smesh.Mesh( Box_1 ) +Mesh_1.Segment().NumberOfSegments(15) +Mesh_1.Triangle() +Mesh_1.Compute() + +# define arguments for MakePolyLine + +segments = [] +# between nodes 20 and 1, default plane +segments.append( SMESH.PolySegment( 20, 0, 1, 0, smesh.MakeDirStruct(0,0,0) )) +# between nodes 1 and 100, default plane +segments.append( SMESH.PolySegment( 1, 0, 200, 0, smesh.MakeDirStruct(0,0,0) )) +# between nodes 200 and edge (578, 577), plane includes vector (1,1,1) +segments.append( SMESH.PolySegment( 200, 0, 578, 577, smesh.MakeDirStruct(1,1,1) )) + +Mesh_1.MakePolyLine( segments, "1D group") + + +if salome.sg.hasDesktop(): + salome.sg.updateObjBrowser() diff --git a/doc/salome/examples/extrusion_penta_biquad.py b/doc/salome/examples/extrusion_penta_biquad.py new file mode 100644 index 000000000..b98f8cd4b --- /dev/null +++ b/doc/salome/examples/extrusion_penta_biquad.py @@ -0,0 +1,54 @@ +# -*- coding: utf-8 -*- + +import sys +import salome + +salome.salome_init() + +import GEOM +from salome.geom import geomBuilder +import math +import SALOMEDS + +geompy = geomBuilder.New() + +O = geompy.MakeVertex(0, 0, 0) +OX = geompy.MakeVectorDXDYDZ(1, 0, 0) +OY = geompy.MakeVectorDXDYDZ(0, 1, 0) +OZ = geompy.MakeVectorDXDYDZ(0, 0, 1) +Divided_Disk_1 = geompy.MakeDividedDisk(100, 1, GEOM.SQUARE) +geompy.addToStudy( O, 'O' ) +geompy.addToStudy( OX, 'OX' ) +geompy.addToStudy( OY, 'OY' ) +geompy.addToStudy( OZ, 'OZ' ) +geompy.addToStudy( Divided_Disk_1, 'Divided Disk_1' ) + +import SMESH, SALOMEDS +from salome.smesh import smeshBuilder + +smesh = smeshBuilder.New() +aFilterManager = smesh.CreateFilterManager() +Mesh_1 = smesh.Mesh(Divided_Disk_1) +Regular_1D = Mesh_1.Segment() +Number_of_Segments_1 = Regular_1D.NumberOfSegments(6) +Quadrangle_2D = Mesh_1.Quadrangle(algo=smeshBuilder.QUADRANGLE) +isDone = Mesh_1.Compute() +aMaxElementLength2D0x5d7fdf0 = aFilterManager.CreateMaxElementLength2D() +isDone = Mesh_1.QuadToTriObject( Mesh_1, ) +Mesh_1.ExtrusionSweepObjects( [ Mesh_1 ], [ Mesh_1 ], [ Mesh_1 ], [ 0, 0, 50 ], 3, 1 ) +Mesh_1.ConvertToQuadratic(0, Mesh_1,True) + +infos = Mesh_1.GetMeshInfo() +print("Number of biquadratic pentahedrons:", infos[SMESH.Entity_BiQuad_Penta]) +if (infos[SMESH.Entity_BiQuad_Penta] != 1080): + raise RuntimeError("Bad number of biquadratic pentahedrons: should be 1080") + +## Set names of Mesh objects +smesh.SetName(Regular_1D.GetAlgorithm(), 'Regular_1D') +smesh.SetName(Quadrangle_2D.GetAlgorithm(), 'Quadrangle_2D') +smesh.SetName(Number_of_Segments_1, 'Number of Segments_1') +smesh.SetName(Mesh_1.GetMesh(), 'Mesh_1') + + +if salome.sg.hasDesktop(): + salome.sg.updateObjBrowser() diff --git a/doc/salome/examples/grouping_elements_ex03.py b/doc/salome/examples/grouping_elements_ex03.py index 19ce71311..97e1de945 100644 --- a/doc/salome/examples/grouping_elements_ex03.py +++ b/doc/salome/examples/grouping_elements_ex03.py @@ -28,22 +28,22 @@ critaria = [ \ ] filt = smesh.GetFilterFromCriteria( critaria ) filtGroup = mesh.GroupOnFilter( SMESH.FACE, "group on filter", filt ) -print("Group on filter contains %s elemens" % filtGroup.Size()) +print("Group on filter contains %s elements" % filtGroup.Size()) # group on filter is updated if the mesh is modified hyp1D.SetStartLength( 2.5 ) hyp1D.SetEndLength( 2.5 ) mesh.Compute() -print("After mesh change, group on filter contains %s elemens" % filtGroup.Size()) +print("After mesh change, group on filter contains %s elements" % filtGroup.Size()) # set a new filter defining the group filt2 = smesh.GetFilter( SMESH.FACE, SMESH.FT_RangeOfIds, "1-50" ) filtGroup.SetFilter( filt2 ) -print("With a new filter, group on filter contains %s elemens" % filtGroup.Size()) +print("With a new filter, group on filter contains %s elements" % filtGroup.Size()) # group is updated at modification of the filter filt2.SetCriteria( [ smesh.GetCriterion( SMESH.FACE, SMESH.FT_RangeOfIds, "1-70" )]) filtIDs3 = filtGroup.GetIDs() -print("After filter modification, group on filter contains %s elemens" % filtGroup.Size()) +print("After filter modification, group on filter contains %s elements" % filtGroup.Size()) salome.sg.updateObjBrowser() diff --git a/doc/salome/examples/quality_controls_defl.py b/doc/salome/examples/quality_controls_defl.py new file mode 100644 index 000000000..9c018e8de --- /dev/null +++ b/doc/salome/examples/quality_controls_defl.py @@ -0,0 +1,45 @@ +# Deflection 2D + + +import salome +salome.salome_init() +from salome.geom import geomBuilder +geompy = geomBuilder.New() + +import SMESH +from salome.smesh import smeshBuilder +smesh = smeshBuilder.New() + +# fuse a box and a sphere +Sphere_1 = geompy.MakeSphereR(100) +Box_1 = geompy.MakeBoxDXDYDZ(200, 200, 200) +Fuse = geompy.MakeFuse( Sphere_1, Box_1, theName="box + sphere" ) + +# create a mesh +mesh = smesh.Mesh( Fuse, "Deflection_2D") +algo = mesh.Segment() +algo.LocalLength(35) +algo = mesh.Triangle() +mesh.Compute() + +# get min and max deflection +minMax = mesh.GetMinMax( SMESH.FT_Deflection2D ) +print("min and max deflection: ", minMax) + +# get deflection of a certain face +faceID = mesh.NbEdges() + mesh.NbFaces() +defl = mesh.FunctorValue( SMESH.FT_Deflection2D, faceID ) +print("deflection of face %s = %s" % ( faceID, defl )) + +margin = minMax[1] / 2 + +# get all faces with deflection LESS than the margin +aFilter = smesh.GetFilter(SMESH.FACE, SMESH.FT_Deflection2D, '<', margin, mesh=mesh) +anIds = aFilter.GetIDs() +print("%s faces have deflection less than %s" %( len(anIds), margin )) + +# create a group of faces with deflection MORE than the margin +aGroup = mesh.MakeGroup("Deflection > " + repr(margin), SMESH.FACE, SMESH.FT_Deflection2D,'>',margin) +print("%s faces have deflection more than %s: %s ..." %( aGroup.Size(), margin, aGroup.GetIDs()[:10] )) + +salome.sg.updateObjBrowser() diff --git a/doc/salome/examples/tests.set b/doc/salome/examples/tests.set index d7744d4f8..2cf9698d1 100644 --- a/doc/salome/examples/tests.set +++ b/doc/salome/examples/tests.set @@ -46,6 +46,7 @@ SET(BAD_TESTS SET(GOOD_TESTS cartesian_algo.py + create_penta_biquad.py creating_meshes_ex02.py creating_meshes_ex04.py creating_meshes_ex06.py @@ -66,6 +67,7 @@ SET(GOOD_TESTS defining_hypotheses_ex15.py defining_hypotheses_ex16.py defining_hypotheses_adaptive1d.py + extrusion_penta_biquad.py filters_ex01.py filters_ex03.py filters_ex04.py @@ -154,6 +156,7 @@ SET(GOOD_TESTS quality_controls_ex17.py quality_controls_ex18.py quality_controls_ex19.py + quality_controls_defl.py transforming_meshes_ex01.py transforming_meshes_ex02.py transforming_meshes_ex03.py diff --git a/doc/salome/gui/SMESH/doxyfile.in b/doc/salome/gui/SMESH/doxyfile.in index 164ad9220..2b716b2c0 100755 --- a/doc/salome/gui/SMESH/doxyfile.in +++ b/doc/salome/gui/SMESH/doxyfile.in @@ -41,6 +41,7 @@ WARNINGS = YES INPUT = @CMAKE_CURRENT_SOURCE_DIR@/input $(GEOM_ROOT_DIR)/share/doc/salome/gui/GEOM/input FILE_PATTERNS = *.doc EXCLUDE = +EXCLUDE_PATTERNS = tui_*.doc IMAGE_PATH = $(GEOM_ROOT_DIR)/share/doc/salome/gui/GEOM @CMAKE_CURRENT_SOURCE_DIR@/images EXAMPLE_PATH = @CMAKE_SOURCE_DIR@/doc/salome/examples @CMAKE_SOURCE_DIR@/src/SMESH_SWIG diff --git a/doc/salome/gui/SMESH/images/deflection_2d.png b/doc/salome/gui/SMESH/images/deflection_2d.png new file mode 100644 index 000000000..f8159622f Binary files /dev/null and b/doc/salome/gui/SMESH/images/deflection_2d.png differ diff --git a/doc/salome/gui/SMESH/input/about_filters.doc b/doc/salome/gui/SMESH/input/about_filters.doc index 7468931a1..0519da4f5 100644 --- a/doc/salome/gui/SMESH/input/about_filters.doc +++ b/doc/salome/gui/SMESH/input/about_filters.doc @@ -7,21 +7,22 @@ specific condition or a set of conditions. Filters can be used to create or edit mesh groups, remove elements from the mesh, control mesh quality by different parameters, etc. -Several criteria can be combined together by using logical operators \a -AND and \a OR. In addition, a filter criterion can be reverted -using logical operator \a NOT. +Several \ref filtering_criteria "filtering criteria" can be combined +together by using logical operators \a AND and \a OR. In addition, a +filter criterion can be reverted using logical operator \a NOT. -Some filtering criteria use the functionality of \ref quality_page "mesh quality controls" -to filter mesh nodes / elements by specific characteristic (Area, Length, etc). +Some filtering criteria use the functionality of \ref quality_page +"mesh quality controls" to filter mesh nodes / elements by specific +characteristic (Area, Length, etc). The functinality of mesh filters is available in both GUI and TUI modes: -- In GUI, filters are available in some dialog boxes via -"Set Filters" button, clicking on which opens the dialog box +- In GUI, filters are available in some dialog boxes via "Set Filters" +button, clicking on which opens the \ref filtering_elements "dialog box" allowing to specify the list of filter criteria to be applied to the -current selection. See \subpage selection_filter_library_page page to learn more -about selection filters and their usage in GUI. +current selection. See \subpage selection_filter_library_page page to +learn more about selection filters and their usage in GUI. - In Python scripts, filters can be used to choose only some mesh entities (nodes or elements) for the operations, which require the diff --git a/doc/salome/gui/SMESH/input/about_quality_controls.doc b/doc/salome/gui/SMESH/input/about_quality_controls.doc index 9dbb5c992..84bcf0d4d 100644 --- a/doc/salome/gui/SMESH/input/about_quality_controls.doc +++ b/doc/salome/gui/SMESH/input/about_quality_controls.doc @@ -37,6 +37,7 @@ Face quality controls:
  • \subpage bare_border_faces_page "Bare border faces"
  • \subpage over_constrained_faces_page "Over-constrained faces"
  • \subpage length_2d_page "Length 2D"
  • +
  • \subpage deflection_2d_page "Deflection 2D"
  • \subpage borders_at_multi_connection_2d_page "Borders at multi-connection 2D"
  • \subpage area_page "Area"
  • \subpage taper_page "Taper"
  • diff --git a/doc/salome/gui/SMESH/input/deflection_2d.doc b/doc/salome/gui/SMESH/input/deflection_2d.doc new file mode 100644 index 000000000..a9d38cde3 --- /dev/null +++ b/doc/salome/gui/SMESH/input/deflection_2d.doc @@ -0,0 +1,25 @@ +/*! + +\page deflection_2d_page Deflection 2D + +\n This quality control criterion consists of calculation of distance +between a mesh face gravity corner and the surface the face discretizes. + +To apply the Deflection 2D quality criterion to your mesh: +
      +
    1. Display your mesh in the viewer.
    2. + +
    3. Choose Controls > Face Controls > Deflection 2D or click +"Deflection 2D" button in the toolbar. + +Your mesh will be displayed in the viewer with faces colored according +to the applied mesh quality control criterion: + +\image html deflection_2d.png +
    4. +
    + +
    See Also a sample TUI Script of a +\ref tui_deflection_2d "Deflection 2D quality control" operation. + +*/ diff --git a/doc/salome/gui/SMESH/input/selection_filter_library.doc b/doc/salome/gui/SMESH/input/selection_filter_library.doc index 03438c490..97d63ec02 100644 --- a/doc/salome/gui/SMESH/input/selection_filter_library.doc +++ b/doc/salome/gui/SMESH/input/selection_filter_library.doc @@ -2,6 +2,10 @@ \page selection_filter_library_page Selection filter library +\tableofcontents + +\section selection_filter_library Filter library + \n Selection filter library allows creating and storing in files the filters that can be later reused for operations on meshes. You can access it from the Main Menu via Tools / Selection filter library. @@ -18,8 +22,7 @@ the current study. You can \b Add or \b Delete filters. \n In Filter name box you can specify the name for your filter. By default it is prefixed with the corresponding entity type. -\anchor filtering_elements -

    Filter Dialog

    +\section filtering_elements Filter Dialog When we use filters during group creation or another operation (by clicking Set Filter button in the corresponding dialog), the @@ -64,6 +67,8 @@ in the Library. is no selected mesh in the Object Browser and the filter can not be created. You have to select the mesh and the button will be enabled. +\section filtering_criteria Filtering Criteria + Some criteria are applicable to all Entity types:
    • Belong to Geom selects entities whose all nodes lie on the @@ -231,6 +236,10 @@ normal to the neighboring face and the normal to the selected face is less then angular tolerance (defined in degrees). Selection continues among all neighbor faces of already selected ones.
    • +Deflection 2D selects 2D mesh elements having distance between their gravity +centers and underlying surfaces, which is more, less or equal (within a given Tolerance) to the predefined Threshold Value. See also a +\ref deflection_2d_page "Deflection 2D quality control". +
    • Element Diameter 2D selects triangles and quadrangles composed of the edges and diagonals with a value of length, which is more, less or equal (within a given Tolerance) to the predefined Threshold Value. See also a diff --git a/doc/salome/gui/SMESH/input/smesh_migration.doc b/doc/salome/gui/SMESH/input/smesh_migration.doc index cf0181758..14b048f73 100644 --- a/doc/salome/gui/SMESH/input/smesh_migration.doc +++ b/doc/salome/gui/SMESH/input/smesh_migration.doc @@ -31,7 +31,7 @@ smesh = smeshBuilder.New() Of course, from smesh import * is no more possible. -\n You have to explicitely write smesh.some_method(). +\n You have to explicitly write smesh.some_method(). All algorithms have been transferred from the namespace smesh to the namespace smeshBuilder. \n For instance: @@ -79,7 +79,7 @@ is replaced by: Compound1 = smesh.Concatenate([Mesh_inf.GetMesh(), Mesh_sup.GetMesh()], 0, 1, 1e-05) \endcode -If you need to import a %SMESH Plugin explicitely, keep in mind that they are now located in separate namespaces. +If you need to import a %SMESH Plugin explicitly, keep in mind that they are now located in separate namespaces. \n For instance: \code import StdMeshers diff --git a/doc/salome/gui/SMESH/input/tui_quality_controls.doc b/doc/salome/gui/SMESH/input/tui_quality_controls.doc index 1434c9b07..cb1632c1e 100644 --- a/doc/salome/gui/SMESH/input/tui_quality_controls.doc +++ b/doc/salome/gui/SMESH/input/tui_quality_controls.doc @@ -37,6 +37,9 @@ \section tui_length_2d Length 2D \tui_script{quality_controls_ex11.py} +\section tui_deflection_2d Deflection 2D +\tui_script{quality_controls_defl.py} + \section tui_borders_at_multiconnection_2d Borders at Multiconnection 2D \tui_script{quality_controls_ex12.py} diff --git a/idl/SMESH_Filter.idl b/idl/SMESH_Filter.idl index b71cf922f..2784e4591 100644 --- a/idl/SMESH_Filter.idl +++ b/idl/SMESH_Filter.idl @@ -61,6 +61,7 @@ module SMESH FT_MultiConnection2D, FT_Length, FT_Length2D, + FT_Deflection2D, FT_NodeConnectivityNumber, FT_BelongToMeshGroup, FT_BelongToGeom, @@ -150,6 +151,7 @@ module SMESH typedef sequence Values; Values GetValues(); }; + interface Deflection2D : NumericalFunctor{}; interface MultiConnection : NumericalFunctor{}; interface MultiConnection2D : NumericalFunctor { @@ -585,6 +587,7 @@ module SMESH MaxElementLength3D CreateMaxElementLength3D(); Length CreateLength(); Length2D CreateLength2D(); + Deflection2D CreateDeflection2D(); MultiConnection CreateMultiConnection(); MultiConnection2D CreateMultiConnection2D(); BallDiameter CreateBallDiameter(); diff --git a/idl/SMESH_Gen.idl b/idl/SMESH_Gen.idl index 4e29fa63b..878c3d6a7 100644 --- a/idl/SMESH_Gen.idl +++ b/idl/SMESH_Gen.idl @@ -154,7 +154,7 @@ module SMESH boolean IsEnablePublish(); /*! - * Create a hypothesis that can be shared by differents parts of the mesh. + * Create a hypothesis that can be shared by different parts of the mesh. * An hypothesis is either: * - a method used to generate or modify a part of the mesh (algorithm). * - a parameter or a law used by an algorithm. diff --git a/idl/SMESH_Mesh.idl b/idl/SMESH_Mesh.idl index b17139203..69c41d4d6 100644 --- a/idl/SMESH_Mesh.idl +++ b/idl/SMESH_Mesh.idl @@ -191,6 +191,7 @@ module SMESH Entity_TriQuad_Hexa, Entity_Penta, Entity_Quad_Penta, + Entity_BiQuad_Penta, Entity_Hexagonal_Prism, Entity_Polyhedra, Entity_Quad_Polyhedra, @@ -541,7 +542,7 @@ module SMESH raises (SALOME::SALOME_Exception); /*! - * Remove an hypothesis previouly added with AddHypothesis. + * Remove an hypothesis previously added with AddHypothesis. */ Hypothesis_Status RemoveHypothesis(in GEOM::GEOM_Object aSubObject, in SMESH_Hypothesis anHyp) @@ -675,7 +676,8 @@ module SMESH in boolean isascii ) raises (SALOME::SALOME_Exception); void ExportCGNS( in SMESH_IDSource meshPart, in string file, - in boolean overwrite ) raises (SALOME::SALOME_Exception); + in boolean overwrite, + in boolean groupElemsByType) raises (SALOME::SALOME_Exception); void ExportGMF( in SMESH_IDSource meshPart, in string file, in boolean withRequiredGroups) raises (SALOME::SALOME_Exception); @@ -692,7 +694,7 @@ module SMESH double GetComputeProgress(); /*! - * Get informations about mesh contents + * Get information about mesh contents */ long NbNodes() raises (SALOME::SALOME_Exception); diff --git a/idl/SMESH_MeshEditor.idl b/idl/SMESH_MeshEditor.idl index ea19b5ebe..9d568ff16 100644 --- a/idl/SMESH_MeshEditor.idl +++ b/idl/SMESH_MeshEditor.idl @@ -57,6 +57,24 @@ module SMESH }; + // structure used in MakePolyLine() to define a cutting plane + struct PolySegment + { + // point 1: if node1ID2 > 0, then the point is in the middle of a face edge defined + // by two nodes, else it is at node1ID1 + long node1ID1; + long node1ID2; + + // point 2: if node2ID2 > 0, then the point is in the middle of a face edge defined + // by two nodes, else it is at node2ID1 + long node2ID1; + long node2ID2; + + DirStruct vector; // vector on the plane; to use a default plane set vector = (0,0,0) + }; + typedef sequence ListOfPolySegments; + + /*! * This interface makes modifications on the Mesh - removing elements and nodes etc. */ @@ -751,7 +769,31 @@ module SMESH * Return point state in a closed 2D mesh in terms of TopAbs_State enumeration. * TopAbs_UNKNOWN state means that either mesh is wrong or the analysis fails. */ - short GetPointState(in double x, in double y, in double z) + short GetPointState(in double x, in double y, in double z) + raises (SALOME::SALOME_Exception); + + /*! + * Check if a 2D mesh is manifold + */ + boolean IsManifold() + raises (SALOME::SALOME_Exception); + + /*! + * Check if orientation of 2D elements is coherent + */ + boolean IsCoherentOrientation2D() + raises (SALOME::SALOME_Exception); + + /*! + * Returns all or only closed FreeBorder's. + */ + ListOfFreeBorders FindFreeBorders(in boolean closedOnly) + raises (SALOME::SALOME_Exception); + + /*! + * Fill with 2D elements a hole defined by a FreeBorder. + */ + void FillHole(in FreeBorder hole) raises (SALOME::SALOME_Exception); /*! @@ -1184,7 +1226,28 @@ module SMESH in GEOM::GEOM_Object theShape, in string groupName, in double_array theNodesCoords, - out array_of_long_array GroupsOfNodes) + out array_of_long_array GroupsOfNodes) + raises (SALOME::SALOME_Exception); + + + /*! + * \brief Create a polyline consisting of 1D mesh elements each lying on a 2D element of + * the initial mesh. Positions of new nodes are found by cutting the mesh by the + * plane passing through pairs of points specified by each PolySegment structure. + * If there are several paths connecting a pair of points, the shortest path is + * selected by the module. Position of the cutting plane is defined by the two + * points and an optional vector lying on the plane specified by a PolySegment. + * By default the vector is defined by Mesh module as following. A middle point + * of the two given points is computed. The middle point is projected to the mesh. + * The vector goes from the middle point to the projection point. In case of planar + * mesh, the vector is normal to the mesh. + * \param [inout] segments - PolySegment's defining positions of cutting planes. + * Return the used vector which goes from the middle point to its projection. + * \param [in] groupName - optional name of a group where created mesh segments will + * be added. + */ + void MakePolyLine(inout ListOfPolySegments segments, + in string groupName) raises (SALOME::SALOME_Exception); }; }; diff --git a/resources/CMakeLists.txt b/resources/CMakeLists.txt index d2801c905..6db2127eb 100755 --- a/resources/CMakeLists.txt +++ b/resources/CMakeLists.txt @@ -228,6 +228,7 @@ SET(SMESH_RESOURCES_FILES mesh_quality.png mesh_show.png mesh_hide.png + mesh_deflection.png ) INSTALL(FILES ${SMESH_RESOURCES_FILES} DESTINATION ${SALOME_SMESH_INSTALL_RES_DATA}) diff --git a/resources/mesh_deflection.png b/resources/mesh_deflection.png new file mode 100644 index 000000000..f9d8542dc Binary files /dev/null and b/resources/mesh_deflection.png differ diff --git a/src/Controls/SMESH_Controls.cxx b/src/Controls/SMESH_Controls.cxx index 9485d983e..f86b56387 100644 --- a/src/Controls/SMESH_Controls.cxx +++ b/src/Controls/SMESH_Controls.cxx @@ -23,6 +23,7 @@ #include "SMESH_ControlsDef.hxx" #include "SMDS_BallElement.hxx" +#include "SMDS_FacePosition.hxx" #include "SMDS_Iterator.hxx" #include "SMDS_Mesh.hxx" #include "SMDS_MeshElement.hxx" @@ -41,13 +42,16 @@ #include #include #include +#include #include #include +#include #include #include #include #include #include +#include #include #include #include @@ -95,6 +99,15 @@ namespace { v2.Magnitude() < gp::Resolution() ? 0 : v1.Angle( v2 ); } + inline double getCos2( const gp_XYZ& P1, const gp_XYZ& P2, const gp_XYZ& P3 ) + { + gp_Vec v1( P1 - P2 ), v2( P3 - P2 ); + double dot = v1 * v2, len1 = v1.SquareMagnitude(), len2 = v2.SquareMagnitude(); + + return ( dot < 0 || len1 < gp::Resolution() || len2 < gp::Resolution() ? -1 : + dot * dot / len1 / len2 ); + } + inline double getArea( const gp_XYZ& P1, const gp_XYZ& P2, const gp_XYZ& P3 ) { gp_Vec aVec1( P2 - P1 ); @@ -261,13 +274,10 @@ bool NumericalFunctor::GetPoints(const SMDS_MeshElement* anElem, } if ( anIter ) { - double xyz[3]; + SMESH_NodeXYZ p; while( anIter->more() ) { - if ( const SMDS_MeshNode* aNode = static_cast( anIter->next() )) - { - aNode->GetXYZ( xyz ); - theRes.push_back( gp_XYZ( xyz[0], xyz[1], xyz[2] )); - } + if ( p.Set( anIter->next() )) + theRes.push_back( p ); } } @@ -616,7 +626,8 @@ double MaxElementLength3D::GetValue( long theElementId ) aVal = Max(aVal,Max(L7,L8)); break; } - case SMDSEntity_Quad_Penta: { // quadratic pentas + case SMDSEntity_Quad_Penta: + case SMDSEntity_BiQuad_Penta: { // quadratic pentas double L1 = getDistance(P( 1 ),P( 7 )) + getDistance(P( 7 ),P( 2 )); double L2 = getDistance(P( 2 ),P( 8 )) + getDistance(P( 8 ),P( 3 )); double L3 = getDistance(P( 3 ),P( 9 )) + getDistance(P( 9 ),P( 1 )); @@ -712,21 +723,25 @@ SMDSAbs_ElementType MaxElementLength3D::GetType() const double MinimumAngle::GetValue( const TSequenceOfXYZ& P ) { - double aMin; - - if (P.size() <3) + if ( P.size() < 3 ) return 0.; - aMin = getAngle(P( P.size() ), P( 1 ), P( 2 )); - aMin = Min(aMin,getAngle(P( P.size()-1 ), P( P.size() ), P( 1 ))); + double aMaxCos2; + + aMaxCos2 = getCos2( P( P.size() ), P( 1 ), P( 2 )); + aMaxCos2 = Max( aMaxCos2, getCos2( P( P.size()-1 ), P( P.size() ), P( 1 ))); for ( size_t i = 2; i < P.size(); i++ ) { - double A0 = getAngle( P( i-1 ), P( i ), P( i+1 ) ); - aMin = Min(aMin,A0); + double A0 = getCos2( P( i-1 ), P( i ), P( i+1 ) ); + aMaxCos2 = Max( aMaxCos2, A0 ); } + if ( aMaxCos2 < 0 ) + return 0; // all nodes coincide - return aMin * 180.0 / M_PI; + double cos = sqrt( aMaxCos2 ); + if ( cos >= 1 ) return 0; + return acos( cos ) * 180.0 / M_PI; } double MinimumAngle::GetBadRate( double Value, int nbNodes ) const @@ -785,58 +800,51 @@ double AspectRatio::GetValue( const TSequenceOfXYZ& P ) if ( nbNodes == 3 ) { // Compute lengths of the sides - std::vector< double > aLen (nbNodes); - for ( int i = 0; i < nbNodes - 1; i++ ) - aLen[ i ] = getDistance( P( i + 1 ), P( i + 2 ) ); - aLen[ nbNodes - 1 ] = getDistance( P( 1 ), P( nbNodes ) ); + double aLen1 = getDistance( P( 1 ), P( 2 )); + double aLen2 = getDistance( P( 2 ), P( 3 )); + double aLen3 = getDistance( P( 3 ), P( 1 )); // Q = alfa * h * p / S, where // // alfa = sqrt( 3 ) / 6 // h - length of the longest edge // p - half perimeter // S - triangle surface - const double alfa = sqrt( 3. ) / 6.; - double maxLen = Max( aLen[ 0 ], Max( aLen[ 1 ], aLen[ 2 ] ) ); - double half_perimeter = ( aLen[0] + aLen[1] + aLen[2] ) / 2.; - double anArea = getArea( P( 1 ), P( 2 ), P( 3 ) ); + const double alfa = sqrt( 3. ) / 6.; + double maxLen = Max( aLen1, Max( aLen2, aLen3 )); + double half_perimeter = ( aLen1 + aLen2 + aLen3 ) / 2.; + double anArea = getArea( P( 1 ), P( 2 ), P( 3 )); if ( anArea <= theEps ) return theInf; return alfa * maxLen * half_perimeter / anArea; } else if ( nbNodes == 6 ) { // quadratic triangles // Compute lengths of the sides - std::vector< double > aLen (3); - aLen[0] = getDistance( P(1), P(3) ); - aLen[1] = getDistance( P(3), P(5) ); - aLen[2] = getDistance( P(5), P(1) ); - // Q = alfa * h * p / S, where - // - // alfa = sqrt( 3 ) / 6 - // h - length of the longest edge - // p - half perimeter - // S - triangle surface - const double alfa = sqrt( 3. ) / 6.; - double maxLen = Max( aLen[ 0 ], Max( aLen[ 1 ], aLen[ 2 ] ) ); - double half_perimeter = ( aLen[0] + aLen[1] + aLen[2] ) / 2.; - double anArea = getArea( P(1), P(3), P(5) ); + double aLen1 = getDistance( P( 1 ), P( 3 )); + double aLen2 = getDistance( P( 3 ), P( 5 )); + double aLen3 = getDistance( P( 5 ), P( 1 )); + // algo same as for the linear triangle + const double alfa = sqrt( 3. ) / 6.; + double maxLen = Max( aLen1, Max( aLen2, aLen3 )); + double half_perimeter = ( aLen1 + aLen2 + aLen3 ) / 2.; + double anArea = getArea( P( 1 ), P( 3 ), P( 5 )); if ( anArea <= theEps ) return theInf; return alfa * maxLen * half_perimeter / anArea; } else if( nbNodes == 4 ) { // quadrangle // Compute lengths of the sides - std::vector< double > aLen (4); + double aLen[4]; aLen[0] = getDistance( P(1), P(2) ); aLen[1] = getDistance( P(2), P(3) ); aLen[2] = getDistance( P(3), P(4) ); aLen[3] = getDistance( P(4), P(1) ); // Compute lengths of the diagonals - std::vector< double > aDia (2); + double aDia[2]; aDia[0] = getDistance( P(1), P(3) ); aDia[1] = getDistance( P(2), P(4) ); // Compute areas of all triangles which can be built // taking three nodes of the quadrangle - std::vector< double > anArea (4); + double anArea[4]; anArea[0] = getArea( P(1), P(2), P(3) ); anArea[1] = getArea( P(1), P(2), P(4) ); anArea[2] = getArea( P(1), P(3), P(4) ); @@ -852,35 +860,35 @@ double AspectRatio::GetValue( const TSequenceOfXYZ& P ) // Si - areas of the triangles const double alpha = sqrt( 1 / 32. ); double L = Max( aLen[ 0 ], - Max( aLen[ 1 ], - Max( aLen[ 2 ], - Max( aLen[ 3 ], - Max( aDia[ 0 ], aDia[ 1 ] ) ) ) ) ); + Max( aLen[ 1 ], + Max( aLen[ 2 ], + Max( aLen[ 3 ], + Max( aDia[ 0 ], aDia[ 1 ] ) ) ) ) ); double C1 = sqrt( ( aLen[0] * aLen[0] + aLen[1] * aLen[1] + aLen[2] * aLen[2] + aLen[3] * aLen[3] ) / 4. ); double C2 = Min( anArea[ 0 ], - Min( anArea[ 1 ], - Min( anArea[ 2 ], anArea[ 3 ] ) ) ); + Min( anArea[ 1 ], + Min( anArea[ 2 ], anArea[ 3 ] ) ) ); if ( C2 <= theEps ) return theInf; return alpha * L * C1 / C2; } else if( nbNodes == 8 || nbNodes == 9 ) { // nbNodes==8 - quadratic quadrangle // Compute lengths of the sides - std::vector< double > aLen (4); + double aLen[4]; aLen[0] = getDistance( P(1), P(3) ); aLen[1] = getDistance( P(3), P(5) ); aLen[2] = getDistance( P(5), P(7) ); aLen[3] = getDistance( P(7), P(1) ); // Compute lengths of the diagonals - std::vector< double > aDia (2); + double aDia[2]; aDia[0] = getDistance( P(1), P(5) ); aDia[1] = getDistance( P(3), P(7) ); // Compute areas of all triangles which can be built // taking three nodes of the quadrangle - std::vector< double > anArea (4); + double anArea[4]; anArea[0] = getArea( P(1), P(3), P(5) ); anArea[1] = getArea( P(1), P(3), P(7) ); anArea[2] = getArea( P(1), P(5), P(7) ); @@ -1552,246 +1560,240 @@ SMDSAbs_ElementType Length::GetType() const */ //================================================================================ -double Length2D::GetValue( long theElementId ) +double Length2D::GetValue( const TSequenceOfXYZ& P ) { - TSequenceOfXYZ P; + double aVal = 0; + int len = P.size(); + SMDSAbs_EntityType aType = P.getElementEntity(); - if ( GetPoints( theElementId, P )) - { - double aVal = 0; - int len = P.size(); - SMDSAbs_EntityType aType = P.getElementEntity(); - - switch (aType) { - case SMDSEntity_Edge: - if (len == 2) - aVal = getDistance( P( 1 ), P( 2 ) ); - break; - case SMDSEntity_Quad_Edge: - if (len == 3) // quadratic edge - aVal = getDistance(P( 1 ),P( 3 )) + getDistance(P( 3 ),P( 2 )); - break; - case SMDSEntity_Triangle: - if (len == 3){ // triangles - double L1 = getDistance(P( 1 ),P( 2 )); - double L2 = getDistance(P( 2 ),P( 3 )); - double L3 = getDistance(P( 3 ),P( 1 )); - aVal = Min(L1,Min(L2,L3)); - } - break; - case SMDSEntity_Quadrangle: - if (len == 4){ // quadrangles - double L1 = getDistance(P( 1 ),P( 2 )); - double L2 = getDistance(P( 2 ),P( 3 )); - double L3 = getDistance(P( 3 ),P( 4 )); - double L4 = getDistance(P( 4 ),P( 1 )); - aVal = Min(Min(L1,L2),Min(L3,L4)); - } - break; - case SMDSEntity_Quad_Triangle: - case SMDSEntity_BiQuad_Triangle: - if (len >= 6){ // quadratic triangles - double L1 = getDistance(P( 1 ),P( 2 )) + getDistance(P( 2 ),P( 3 )); - double L2 = getDistance(P( 3 ),P( 4 )) + getDistance(P( 4 ),P( 5 )); - double L3 = getDistance(P( 5 ),P( 6 )) + getDistance(P( 6 ),P( 1 )); - aVal = Min(L1,Min(L2,L3)); - } - break; - case SMDSEntity_Quad_Quadrangle: - case SMDSEntity_BiQuad_Quadrangle: - if (len >= 8){ // quadratic quadrangles - double L1 = getDistance(P( 1 ),P( 2 )) + getDistance(P( 2 ),P( 3 )); - double L2 = getDistance(P( 3 ),P( 4 )) + getDistance(P( 4 ),P( 5 )); - double L3 = getDistance(P( 5 ),P( 6 )) + getDistance(P( 6 ),P( 7 )); - double L4 = getDistance(P( 7 ),P( 8 )) + getDistance(P( 8 ),P( 1 )); - aVal = Min(Min(L1,L2),Min(L3,L4)); - } - break; - case SMDSEntity_Tetra: - if (len == 4){ // tetrahedra - double L1 = getDistance(P( 1 ),P( 2 )); - double L2 = getDistance(P( 2 ),P( 3 )); - double L3 = getDistance(P( 3 ),P( 1 )); - double L4 = getDistance(P( 1 ),P( 4 )); - double L5 = getDistance(P( 2 ),P( 4 )); - double L6 = getDistance(P( 3 ),P( 4 )); - aVal = Min(Min(Min(L1,L2),Min(L3,L4)),Min(L5,L6)); - } - break; - case SMDSEntity_Pyramid: - if (len == 5){ // piramids - double L1 = getDistance(P( 1 ),P( 2 )); - double L2 = getDistance(P( 2 ),P( 3 )); - double L3 = getDistance(P( 3 ),P( 4 )); - double L4 = getDistance(P( 4 ),P( 1 )); - double L5 = getDistance(P( 1 ),P( 5 )); - double L6 = getDistance(P( 2 ),P( 5 )); - double L7 = getDistance(P( 3 ),P( 5 )); - double L8 = getDistance(P( 4 ),P( 5 )); - - aVal = Min(Min(Min(L1,L2),Min(L3,L4)),Min(L5,L6)); - aVal = Min(aVal,Min(L7,L8)); - } - break; - case SMDSEntity_Penta: - if (len == 6) { // pentaidres - double L1 = getDistance(P( 1 ),P( 2 )); - double L2 = getDistance(P( 2 ),P( 3 )); - double L3 = getDistance(P( 3 ),P( 1 )); - double L4 = getDistance(P( 4 ),P( 5 )); - double L5 = getDistance(P( 5 ),P( 6 )); - double L6 = getDistance(P( 6 ),P( 4 )); - double L7 = getDistance(P( 1 ),P( 4 )); - double L8 = getDistance(P( 2 ),P( 5 )); - double L9 = getDistance(P( 3 ),P( 6 )); - - aVal = Min(Min(Min(L1,L2),Min(L3,L4)),Min(L5,L6)); - aVal = Min(aVal,Min(Min(L7,L8),L9)); - } - break; - case SMDSEntity_Hexa: - if (len == 8){ // hexahedron - double L1 = getDistance(P( 1 ),P( 2 )); - double L2 = getDistance(P( 2 ),P( 3 )); - double L3 = getDistance(P( 3 ),P( 4 )); - double L4 = getDistance(P( 4 ),P( 1 )); - double L5 = getDistance(P( 5 ),P( 6 )); - double L6 = getDistance(P( 6 ),P( 7 )); - double L7 = getDistance(P( 7 ),P( 8 )); - double L8 = getDistance(P( 8 ),P( 5 )); - double L9 = getDistance(P( 1 ),P( 5 )); - double L10= getDistance(P( 2 ),P( 6 )); - double L11= getDistance(P( 3 ),P( 7 )); - double L12= getDistance(P( 4 ),P( 8 )); - - aVal = Min(Min(Min(L1,L2),Min(L3,L4)),Min(L5,L6)); - aVal = Min(aVal,Min(Min(L7,L8),Min(L9,L10))); - aVal = Min(aVal,Min(L11,L12)); - } - break; - case SMDSEntity_Quad_Tetra: - if (len == 10){ // quadratic tetraidrs - double L1 = getDistance(P( 1 ),P( 5 )) + getDistance(P( 5 ),P( 2 )); - double L2 = getDistance(P( 2 ),P( 6 )) + getDistance(P( 6 ),P( 3 )); - double L3 = getDistance(P( 3 ),P( 7 )) + getDistance(P( 7 ),P( 1 )); - double L4 = getDistance(P( 1 ),P( 8 )) + getDistance(P( 8 ),P( 4 )); - double L5 = getDistance(P( 2 ),P( 9 )) + getDistance(P( 9 ),P( 4 )); - double L6 = getDistance(P( 3 ),P( 10 )) + getDistance(P( 10 ),P( 4 )); - aVal = Min(Min(Min(L1,L2),Min(L3,L4)),Min(L5,L6)); - } - break; - case SMDSEntity_Quad_Pyramid: - if (len == 13){ // quadratic piramids - double L1 = getDistance(P( 1 ),P( 6 )) + getDistance(P( 6 ),P( 2 )); - double L2 = getDistance(P( 2 ),P( 7 )) + getDistance(P( 7 ),P( 3 )); - double L3 = getDistance(P( 3 ),P( 8 )) + getDistance(P( 8 ),P( 4 )); - double L4 = getDistance(P( 4 ),P( 9 )) + getDistance(P( 9 ),P( 1 )); - double L5 = getDistance(P( 1 ),P( 10 )) + getDistance(P( 10 ),P( 5 )); - double L6 = getDistance(P( 2 ),P( 11 )) + getDistance(P( 11 ),P( 5 )); - double L7 = getDistance(P( 3 ),P( 12 )) + getDistance(P( 12 ),P( 5 )); - double L8 = getDistance(P( 4 ),P( 13 )) + getDistance(P( 13 ),P( 5 )); - aVal = Min(Min(Min(L1,L2),Min(L3,L4)),Min(L5,L6)); - aVal = Min(aVal,Min(L7,L8)); - } - break; - case SMDSEntity_Quad_Penta: - if (len == 15){ // quadratic pentaidres - double L1 = getDistance(P( 1 ),P( 7 )) + getDistance(P( 7 ),P( 2 )); - double L2 = getDistance(P( 2 ),P( 8 )) + getDistance(P( 8 ),P( 3 )); - double L3 = getDistance(P( 3 ),P( 9 )) + getDistance(P( 9 ),P( 1 )); - double L4 = getDistance(P( 4 ),P( 10 )) + getDistance(P( 10 ),P( 5 )); - double L5 = getDistance(P( 5 ),P( 11 )) + getDistance(P( 11 ),P( 6 )); - double L6 = getDistance(P( 6 ),P( 12 )) + getDistance(P( 12 ),P( 4 )); - double L7 = getDistance(P( 1 ),P( 13 )) + getDistance(P( 13 ),P( 4 )); - double L8 = getDistance(P( 2 ),P( 14 )) + getDistance(P( 14 ),P( 5 )); - double L9 = getDistance(P( 3 ),P( 15 )) + getDistance(P( 15 ),P( 6 )); - aVal = Min(Min(Min(L1,L2),Min(L3,L4)),Min(L5,L6)); - aVal = Min(aVal,Min(Min(L7,L8),L9)); - } - break; - case SMDSEntity_Quad_Hexa: - case SMDSEntity_TriQuad_Hexa: - if (len >= 20) { // quadratic hexaider - double L1 = getDistance(P( 1 ),P( 9 )) + getDistance(P( 9 ),P( 2 )); - double L2 = getDistance(P( 2 ),P( 10 )) + getDistance(P( 10 ),P( 3 )); - double L3 = getDistance(P( 3 ),P( 11 )) + getDistance(P( 11 ),P( 4 )); - double L4 = getDistance(P( 4 ),P( 12 )) + getDistance(P( 12 ),P( 1 )); - double L5 = getDistance(P( 5 ),P( 13 )) + getDistance(P( 13 ),P( 6 )); - double L6 = getDistance(P( 6 ),P( 14 )) + getDistance(P( 14 ),P( 7 )); - double L7 = getDistance(P( 7 ),P( 15 )) + getDistance(P( 15 ),P( 8 )); - double L8 = getDistance(P( 8 ),P( 16 )) + getDistance(P( 16 ),P( 5 )); - double L9 = getDistance(P( 1 ),P( 17 )) + getDistance(P( 17 ),P( 5 )); - double L10= getDistance(P( 2 ),P( 18 )) + getDistance(P( 18 ),P( 6 )); - double L11= getDistance(P( 3 ),P( 19 )) + getDistance(P( 19 ),P( 7 )); - double L12= getDistance(P( 4 ),P( 20 )) + getDistance(P( 20 ),P( 8 )); - aVal = Min(Min(Min(L1,L2),Min(L3,L4)),Min(L5,L6)); - aVal = Min(aVal,Min(Min(L7,L8),Min(L9,L10))); - aVal = Min(aVal,Min(L11,L12)); - } - break; - case SMDSEntity_Polygon: - if ( len > 1 ) { - aVal = getDistance( P(1), P( P.size() )); - for ( size_t i = 1; i < P.size(); ++i ) - aVal = Min( aVal, getDistance( P( i ), P( i+1 ))); - } - break; - case SMDSEntity_Quad_Polygon: - if ( len > 2 ) { - aVal = getDistance( P(1), P( P.size() )) + getDistance( P(P.size()), P( P.size()-1 )); - for ( size_t i = 1; i < P.size()-1; i += 2 ) - aVal = Min( aVal, getDistance( P( i ), P( i+1 )) + getDistance( P( i+1 ), P( i+2 ))); - } - break; - case SMDSEntity_Hexagonal_Prism: - if (len == 12) { // hexagonal prism - double L1 = getDistance(P( 1 ),P( 2 )); - double L2 = getDistance(P( 2 ),P( 3 )); - double L3 = getDistance(P( 3 ),P( 4 )); - double L4 = getDistance(P( 4 ),P( 5 )); - double L5 = getDistance(P( 5 ),P( 6 )); - double L6 = getDistance(P( 6 ),P( 1 )); - - double L7 = getDistance(P( 7 ), P( 8 )); - double L8 = getDistance(P( 8 ), P( 9 )); - double L9 = getDistance(P( 9 ), P( 10 )); - double L10= getDistance(P( 10 ),P( 11 )); - double L11= getDistance(P( 11 ),P( 12 )); - double L12= getDistance(P( 12 ),P( 7 )); - - double L13 = getDistance(P( 1 ),P( 7 )); - double L14 = getDistance(P( 2 ),P( 8 )); - double L15 = getDistance(P( 3 ),P( 9 )); - double L16 = getDistance(P( 4 ),P( 10 )); - double L17 = getDistance(P( 5 ),P( 11 )); - double L18 = getDistance(P( 6 ),P( 12 )); - aVal = Min(Min(Min(L1,L2),Min(L3,L4)),Min(L5,L6)); - aVal = Min(aVal, Min(Min(Min(L7,L8),Min(L9,L10)),Min(L11,L12))); - aVal = Min(aVal, Min(Min(Min(L13,L14),Min(L15,L16)),Min(L17,L18))); - } - break; - case SMDSEntity_Polyhedra: - { + switch (aType) { + case SMDSEntity_Edge: + if (len == 2) + aVal = getDistance( P( 1 ), P( 2 ) ); + break; + case SMDSEntity_Quad_Edge: + if (len == 3) // quadratic edge + aVal = getDistance(P( 1 ),P( 3 )) + getDistance(P( 3 ),P( 2 )); + break; + case SMDSEntity_Triangle: + if (len == 3){ // triangles + double L1 = getDistance(P( 1 ),P( 2 )); + double L2 = getDistance(P( 2 ),P( 3 )); + double L3 = getDistance(P( 3 ),P( 1 )); + aVal = Min(L1,Min(L2,L3)); } break; - default: - return 0; + case SMDSEntity_Quadrangle: + if (len == 4){ // quadrangles + double L1 = getDistance(P( 1 ),P( 2 )); + double L2 = getDistance(P( 2 ),P( 3 )); + double L3 = getDistance(P( 3 ),P( 4 )); + double L4 = getDistance(P( 4 ),P( 1 )); + aVal = Min(Min(L1,L2),Min(L3,L4)); } - - if (aVal < 0 ) { - return 0.; + break; + case SMDSEntity_Quad_Triangle: + case SMDSEntity_BiQuad_Triangle: + if (len >= 6){ // quadratic triangles + double L1 = getDistance(P( 1 ),P( 2 )) + getDistance(P( 2 ),P( 3 )); + double L2 = getDistance(P( 3 ),P( 4 )) + getDistance(P( 4 ),P( 5 )); + double L3 = getDistance(P( 5 ),P( 6 )) + getDistance(P( 6 ),P( 1 )); + aVal = Min(L1,Min(L2,L3)); } - - if ( myPrecision >= 0 ) - { - double prec = pow( 10., (double)( myPrecision ) ); - aVal = floor( aVal * prec + 0.5 ) / prec; + break; + case SMDSEntity_Quad_Quadrangle: + case SMDSEntity_BiQuad_Quadrangle: + if (len >= 8){ // quadratic quadrangles + double L1 = getDistance(P( 1 ),P( 2 )) + getDistance(P( 2 ),P( 3 )); + double L2 = getDistance(P( 3 ),P( 4 )) + getDistance(P( 4 ),P( 5 )); + double L3 = getDistance(P( 5 ),P( 6 )) + getDistance(P( 6 ),P( 7 )); + double L4 = getDistance(P( 7 ),P( 8 )) + getDistance(P( 8 ),P( 1 )); + aVal = Min(Min(L1,L2),Min(L3,L4)); } + break; + case SMDSEntity_Tetra: + if (len == 4){ // tetrahedra + double L1 = getDistance(P( 1 ),P( 2 )); + double L2 = getDistance(P( 2 ),P( 3 )); + double L3 = getDistance(P( 3 ),P( 1 )); + double L4 = getDistance(P( 1 ),P( 4 )); + double L5 = getDistance(P( 2 ),P( 4 )); + double L6 = getDistance(P( 3 ),P( 4 )); + aVal = Min(Min(Min(L1,L2),Min(L3,L4)),Min(L5,L6)); + } + break; + case SMDSEntity_Pyramid: + if (len == 5){ // pyramid + double L1 = getDistance(P( 1 ),P( 2 )); + double L2 = getDistance(P( 2 ),P( 3 )); + double L3 = getDistance(P( 3 ),P( 4 )); + double L4 = getDistance(P( 4 ),P( 1 )); + double L5 = getDistance(P( 1 ),P( 5 )); + double L6 = getDistance(P( 2 ),P( 5 )); + double L7 = getDistance(P( 3 ),P( 5 )); + double L8 = getDistance(P( 4 ),P( 5 )); - return aVal; + aVal = Min(Min(Min(L1,L2),Min(L3,L4)),Min(L5,L6)); + aVal = Min(aVal,Min(L7,L8)); + } + break; + case SMDSEntity_Penta: + if (len == 6) { // pentahedron + double L1 = getDistance(P( 1 ),P( 2 )); + double L2 = getDistance(P( 2 ),P( 3 )); + double L3 = getDistance(P( 3 ),P( 1 )); + double L4 = getDistance(P( 4 ),P( 5 )); + double L5 = getDistance(P( 5 ),P( 6 )); + double L6 = getDistance(P( 6 ),P( 4 )); + double L7 = getDistance(P( 1 ),P( 4 )); + double L8 = getDistance(P( 2 ),P( 5 )); + double L9 = getDistance(P( 3 ),P( 6 )); + aVal = Min(Min(Min(L1,L2),Min(L3,L4)),Min(L5,L6)); + aVal = Min(aVal,Min(Min(L7,L8),L9)); + } + break; + case SMDSEntity_Hexa: + if (len == 8){ // hexahedron + double L1 = getDistance(P( 1 ),P( 2 )); + double L2 = getDistance(P( 2 ),P( 3 )); + double L3 = getDistance(P( 3 ),P( 4 )); + double L4 = getDistance(P( 4 ),P( 1 )); + double L5 = getDistance(P( 5 ),P( 6 )); + double L6 = getDistance(P( 6 ),P( 7 )); + double L7 = getDistance(P( 7 ),P( 8 )); + double L8 = getDistance(P( 8 ),P( 5 )); + double L9 = getDistance(P( 1 ),P( 5 )); + double L10= getDistance(P( 2 ),P( 6 )); + double L11= getDistance(P( 3 ),P( 7 )); + double L12= getDistance(P( 4 ),P( 8 )); + + aVal = Min(Min(Min(L1,L2),Min(L3,L4)),Min(L5,L6)); + aVal = Min(aVal,Min(Min(L7,L8),Min(L9,L10))); + aVal = Min(aVal,Min(L11,L12)); + } + break; + case SMDSEntity_Quad_Tetra: + if (len == 10){ // quadratic tetrahedron + double L1 = getDistance(P( 1 ),P( 5 )) + getDistance(P( 5 ),P( 2 )); + double L2 = getDistance(P( 2 ),P( 6 )) + getDistance(P( 6 ),P( 3 )); + double L3 = getDistance(P( 3 ),P( 7 )) + getDistance(P( 7 ),P( 1 )); + double L4 = getDistance(P( 1 ),P( 8 )) + getDistance(P( 8 ),P( 4 )); + double L5 = getDistance(P( 2 ),P( 9 )) + getDistance(P( 9 ),P( 4 )); + double L6 = getDistance(P( 3 ),P( 10 )) + getDistance(P( 10 ),P( 4 )); + aVal = Min(Min(Min(L1,L2),Min(L3,L4)),Min(L5,L6)); + } + break; + case SMDSEntity_Quad_Pyramid: + if (len == 13){ // quadratic pyramid + double L1 = getDistance(P( 1 ),P( 6 )) + getDistance(P( 6 ),P( 2 )); + double L2 = getDistance(P( 2 ),P( 7 )) + getDistance(P( 7 ),P( 3 )); + double L3 = getDistance(P( 3 ),P( 8 )) + getDistance(P( 8 ),P( 4 )); + double L4 = getDistance(P( 4 ),P( 9 )) + getDistance(P( 9 ),P( 1 )); + double L5 = getDistance(P( 1 ),P( 10 )) + getDistance(P( 10 ),P( 5 )); + double L6 = getDistance(P( 2 ),P( 11 )) + getDistance(P( 11 ),P( 5 )); + double L7 = getDistance(P( 3 ),P( 12 )) + getDistance(P( 12 ),P( 5 )); + double L8 = getDistance(P( 4 ),P( 13 )) + getDistance(P( 13 ),P( 5 )); + aVal = Min(Min(Min(L1,L2),Min(L3,L4)),Min(L5,L6)); + aVal = Min(aVal,Min(L7,L8)); + } + break; + case SMDSEntity_Quad_Penta: + case SMDSEntity_BiQuad_Penta: + if (len >= 15){ // quadratic pentahedron + double L1 = getDistance(P( 1 ),P( 7 )) + getDistance(P( 7 ),P( 2 )); + double L2 = getDistance(P( 2 ),P( 8 )) + getDistance(P( 8 ),P( 3 )); + double L3 = getDistance(P( 3 ),P( 9 )) + getDistance(P( 9 ),P( 1 )); + double L4 = getDistance(P( 4 ),P( 10 )) + getDistance(P( 10 ),P( 5 )); + double L5 = getDistance(P( 5 ),P( 11 )) + getDistance(P( 11 ),P( 6 )); + double L6 = getDistance(P( 6 ),P( 12 )) + getDistance(P( 12 ),P( 4 )); + double L7 = getDistance(P( 1 ),P( 13 )) + getDistance(P( 13 ),P( 4 )); + double L8 = getDistance(P( 2 ),P( 14 )) + getDistance(P( 14 ),P( 5 )); + double L9 = getDistance(P( 3 ),P( 15 )) + getDistance(P( 15 ),P( 6 )); + aVal = Min(Min(Min(L1,L2),Min(L3,L4)),Min(L5,L6)); + aVal = Min(aVal,Min(Min(L7,L8),L9)); + } + break; + case SMDSEntity_Quad_Hexa: + case SMDSEntity_TriQuad_Hexa: + if (len >= 20) { // quadratic hexahedron + double L1 = getDistance(P( 1 ),P( 9 )) + getDistance(P( 9 ),P( 2 )); + double L2 = getDistance(P( 2 ),P( 10 )) + getDistance(P( 10 ),P( 3 )); + double L3 = getDistance(P( 3 ),P( 11 )) + getDistance(P( 11 ),P( 4 )); + double L4 = getDistance(P( 4 ),P( 12 )) + getDistance(P( 12 ),P( 1 )); + double L5 = getDistance(P( 5 ),P( 13 )) + getDistance(P( 13 ),P( 6 )); + double L6 = getDistance(P( 6 ),P( 14 )) + getDistance(P( 14 ),P( 7 )); + double L7 = getDistance(P( 7 ),P( 15 )) + getDistance(P( 15 ),P( 8 )); + double L8 = getDistance(P( 8 ),P( 16 )) + getDistance(P( 16 ),P( 5 )); + double L9 = getDistance(P( 1 ),P( 17 )) + getDistance(P( 17 ),P( 5 )); + double L10= getDistance(P( 2 ),P( 18 )) + getDistance(P( 18 ),P( 6 )); + double L11= getDistance(P( 3 ),P( 19 )) + getDistance(P( 19 ),P( 7 )); + double L12= getDistance(P( 4 ),P( 20 )) + getDistance(P( 20 ),P( 8 )); + aVal = Min(Min(Min(L1,L2),Min(L3,L4)),Min(L5,L6)); + aVal = Min(aVal,Min(Min(L7,L8),Min(L9,L10))); + aVal = Min(aVal,Min(L11,L12)); + } + break; + case SMDSEntity_Polygon: + if ( len > 1 ) { + aVal = getDistance( P(1), P( P.size() )); + for ( size_t i = 1; i < P.size(); ++i ) + aVal = Min( aVal, getDistance( P( i ), P( i+1 ))); + } + break; + case SMDSEntity_Quad_Polygon: + if ( len > 2 ) { + aVal = getDistance( P(1), P( P.size() )) + getDistance( P(P.size()), P( P.size()-1 )); + for ( size_t i = 1; i < P.size()-1; i += 2 ) + aVal = Min( aVal, getDistance( P( i ), P( i+1 )) + getDistance( P( i+1 ), P( i+2 ))); + } + break; + case SMDSEntity_Hexagonal_Prism: + if (len == 12) { // hexagonal prism + double L1 = getDistance(P( 1 ),P( 2 )); + double L2 = getDistance(P( 2 ),P( 3 )); + double L3 = getDistance(P( 3 ),P( 4 )); + double L4 = getDistance(P( 4 ),P( 5 )); + double L5 = getDistance(P( 5 ),P( 6 )); + double L6 = getDistance(P( 6 ),P( 1 )); + + double L7 = getDistance(P( 7 ), P( 8 )); + double L8 = getDistance(P( 8 ), P( 9 )); + double L9 = getDistance(P( 9 ), P( 10 )); + double L10= getDistance(P( 10 ),P( 11 )); + double L11= getDistance(P( 11 ),P( 12 )); + double L12= getDistance(P( 12 ),P( 7 )); + + double L13 = getDistance(P( 1 ),P( 7 )); + double L14 = getDistance(P( 2 ),P( 8 )); + double L15 = getDistance(P( 3 ),P( 9 )); + double L16 = getDistance(P( 4 ),P( 10 )); + double L17 = getDistance(P( 5 ),P( 11 )); + double L18 = getDistance(P( 6 ),P( 12 )); + aVal = Min(Min(Min(L1,L2),Min(L3,L4)),Min(L5,L6)); + aVal = Min(aVal, Min(Min(Min(L7,L8),Min(L9,L10)),Min(L11,L12))); + aVal = Min(aVal, Min(Min(Min(L13,L14),Min(L15,L16)),Min(L17,L18))); + } + break; + case SMDSEntity_Polyhedra: + { } - return 0.; + break; + default: + return 0; + } + + if (aVal < 0 ) { + return 0.; + } + + if ( myPrecision >= 0 ) + { + double prec = pow( 10., (double)( myPrecision ) ); + aVal = floor( aVal * prec + 0.5 ) / prec; + } + + return aVal; } double Length2D::GetBadRate( double Value, int /*nbNodes*/ ) const @@ -1906,6 +1908,97 @@ void Length2D::GetValues(TValues& theValues) } } +//================================================================================ +/* + Class : Deflection2D + Description : Functor for calculating number of faces conneted to the edge +*/ +//================================================================================ + +double Deflection2D::GetValue( const TSequenceOfXYZ& P ) +{ + if ( myMesh && P.getElement() ) + { + // get underlying surface + if ( myShapeIndex != P.getElement()->getshapeId() ) + { + mySurface.Nullify(); + myShapeIndex = P.getElement()->getshapeId(); + const TopoDS_Shape& S = + static_cast< const SMESHDS_Mesh* >( myMesh )->IndexToShape( myShapeIndex ); + if ( !S.IsNull() && S.ShapeType() == TopAbs_FACE ) + { + mySurface = new ShapeAnalysis_Surface( BRep_Tool::Surface( TopoDS::Face( S ))); + + GeomLib_IsPlanarSurface isPlaneCheck( mySurface->Surface() ); + if ( isPlaneCheck.IsPlanar() ) + myPlane.reset( new gp_Pln( isPlaneCheck.Plan() )); + else + myPlane.reset(); + } + } + // project gravity center to the surface + if ( !mySurface.IsNull() ) + { + gp_XYZ gc(0,0,0); + gp_XY uv(0,0); + int nbUV = 0; + for ( size_t i = 0; i < P.size(); ++i ) + { + gc += P(i+1); + + if ( const SMDS_FacePosition* fPos = dynamic_cast + ( P.getElement()->GetNode( i )->GetPosition() )) + { + uv.ChangeCoord(1) += fPos->GetUParameter(); + uv.ChangeCoord(2) += fPos->GetVParameter(); + ++nbUV; + } + } + gc /= P.size(); + if ( nbUV ) uv /= nbUV; + + double maxLen = MaxElementLength2D().GetValue( P ); + double tol = 1e-3 * maxLen; + double dist; + if ( myPlane ) + { + dist = myPlane->Distance( gc ); + if ( dist < tol ) + dist = 0; + } + else + { + if ( uv.X() != 0 && uv.Y() != 0 ) // faster way + mySurface->NextValueOfUV( uv, gc, tol, 0.5 * maxLen ); + else + mySurface->ValueOfUV( gc, tol ); + dist = mySurface->Gap(); + } + return Round( dist ); + } + } + return 0; +} + +void Deflection2D::SetMesh( const SMDS_Mesh* theMesh ) +{ + NumericalFunctor::SetMesh( dynamic_cast( theMesh )); + myShapeIndex = -100; + myPlane.reset(); +} + +SMDSAbs_ElementType Deflection2D::GetType() const +{ + return SMDSAbs_Face; +} + +double Deflection2D::GetBadRate( double Value, int /*nbNodes*/ ) const +{ + // meaningless as it is not quality control functor + return Value; +} + //================================================================================ /* Class : MultiConnection diff --git a/src/Controls/SMESH_ControlsDef.hxx b/src/Controls/SMESH_ControlsDef.hxx index 74a4a263d..452b27a39 100644 --- a/src/Controls/SMESH_ControlsDef.hxx +++ b/src/Controls/SMESH_ControlsDef.hxx @@ -27,7 +27,6 @@ #include "SMESH_TypeDefs.hxx" -#include #include #include #include @@ -54,6 +53,9 @@ class SMESHDS_Mesh; class SMESHDS_SubMesh; class SMESHDS_GroupBase; +class BRepClass3d_SolidClassifier; +class ShapeAnalysis_Surface; +class gp_Pln; class gp_Pnt; namespace SMESH{ @@ -293,7 +295,7 @@ namespace SMESH{ */ class SMESHCONTROLS_EXPORT Length2D: public virtual NumericalFunctor{ public: - virtual double GetValue( long theElementId ); + virtual double GetValue( const TSequenceOfXYZ& thePoints ); virtual double GetBadRate( double Value, int nbNodes ) const; virtual SMDSAbs_ElementType GetType() const; struct Value{ @@ -307,6 +309,22 @@ namespace SMESH{ }; typedef boost::shared_ptr Length2DPtr; + /* + Class : Deflection2D + Description : Functor for calculating distance between a face and geometry + */ + class SMESHCONTROLS_EXPORT Deflection2D: public virtual NumericalFunctor{ + public: + virtual void SetMesh( const SMDS_Mesh* theMesh ); + virtual double GetValue( const TSequenceOfXYZ& thePoints ); + virtual double GetBadRate( double Value, int nbNodes ) const; + virtual SMDSAbs_ElementType GetType() const; + private: + Handle(ShapeAnalysis_Surface) mySurface; + int myShapeIndex; + boost::shared_ptr myPlane; + }; + /* Class : MultiConnection Description : Functor for calculating number of faces connected to the edge diff --git a/src/DriverCGNS/DriverCGNS_Write.cxx b/src/DriverCGNS/DriverCGNS_Write.cxx index 844bb863f..4d79e0f7c 100644 --- a/src/DriverCGNS/DriverCGNS_Write.cxx +++ b/src/DriverCGNS/DriverCGNS_Write.cxx @@ -25,6 +25,7 @@ #include "DriverCGNS_Write.hxx" +#include "SMDS_IteratorOnIterators.hxx" #include "SMDS_MeshNode.hxx" #include "SMDS_VolumeTool.hxx" #include "SMESHDS_GroupBase.hxx" @@ -129,6 +130,11 @@ namespace interlaces[SMDSEntity_Quad_Penta] = ids; cgTypes [SMDSEntity_Quad_Penta] = CGNS_ENUMV( PENTA_15 ); } + { + static int ids[] = { 0,2,1,3,5,4,8,7,6,9,11,10,14,13,12,15,16,17 }; // TODO: check CGNS ORDER + interlaces[SMDSEntity_BiQuad_Penta] = ids; + cgTypes [SMDSEntity_BiQuad_Penta] = CGNS_ENUMV( PENTA_18 ); + } { static int ids[] = { 0,3,2,1,4,7,6,5 }; interlaces[SMDSEntity_Hexa] = ids; @@ -330,7 +336,24 @@ Driver_Mesh::Status DriverCGNS_Write::Perform() // write into a section all successive elements of one geom type int iSec; vector< cgsize_t > elemData; - SMDS_ElemIteratorPtr elemIt = myMesh->elementsIterator(); + SMDS_ElemIteratorPtr elemIt = myMesh->elementsIterator(); + vector< SMDS_ElemIteratorPtr > elemItVec; + if ( _elementsByType ) + { + // create an iterator returning all elements by type + for ( int type = SMDSEntity_Node + 1; type < SMDSEntity_Last; ++type ) + { + if ( type == SMDSEntity_Ball ) + continue; // not supported + elemIt = myMesh->elementEntityIterator( SMDSAbs_EntityType( type )); + if ( elemIt->more() ) + elemItVec.push_back( elemIt ); + } + typedef SMDS_IteratorOnIterators< const SMDS_MeshElement*, + vector< SMDS_ElemIteratorPtr > > TVecIterator; + elemIt.reset( new TVecIterator( elemItVec )); + } + const SMDS_MeshElement* elem = elemIt->next(); while ( elem ) { @@ -397,6 +420,15 @@ Driver_Mesh::Status DriverCGNS_Write::Perform() elem = elemIt->more() ? elemIt->next() : 0; continue; } + else // skip NOT SUPPORTED elements + { + while ( elemIt->more() ) + { + elem = elemIt->next(); + if ( elem->GetEntityType() != elemType ) + break; + } + } SMESH_Comment sectionName( cg_ElementTypeName( cgType )); sectionName << " " << startID << " - " << cgID-1; @@ -405,6 +437,7 @@ Driver_Mesh::Status DriverCGNS_Write::Perform() cgID-1, /*nbndry=*/0, &elemData[0], &iSec) != CG_OK ) return addMessage( cg_get_error(), /*fatal = */true ); } + // Write polyhedral volumes // ------------------------- @@ -534,21 +567,33 @@ Driver_Mesh::Status DriverCGNS_Write::Perform() switch ( meshDim ) { case 3: switch ( group->GetType() ) { - case SMDSAbs_Volume: location = CGNS_ENUMV( FaceCenter ); break; // !!! - case SMDSAbs_Face: location = CGNS_ENUMV( FaceCenter ); break; // OK - case SMDSAbs_Edge: location = CGNS_ENUMV( EdgeCenter ); break; // OK +#if CGNS_VERSION > 3130 + case SMDSAbs_Volume: location = CGNS_ENUMV( CellCenter ); break; +#else + case SMDSAbs_Volume: location = CGNS_ENUMV( FaceCenter ); break; +#endif + case SMDSAbs_Face: location = CGNS_ENUMV( FaceCenter ); break; + case SMDSAbs_Edge: location = CGNS_ENUMV( EdgeCenter ); break; default:; } break; case 2: switch ( group->GetType() ) { - case SMDSAbs_Face: location = CGNS_ENUMV( FaceCenter ); break; // ??? - case SMDSAbs_Edge: location = CGNS_ENUMV( EdgeCenter ); break; // OK +#if CGNS_VERSION > 3130 + case SMDSAbs_Face: location = CGNS_ENUMV( CellCenter ); break; +#else + case SMDSAbs_Face: location = CGNS_ENUMV( FaceCenter ); break; +#endif + case SMDSAbs_Edge: location = CGNS_ENUMV( EdgeCenter ); break; default:; } break; case 1: - location = CGNS_ENUMV( EdgeCenter ); break; // ??? +#if CGNS_VERSION > 3130 + location = CGNS_ENUMV( CellCenter ); break; +#else + location = CGNS_ENUMV( EdgeCenter ); break; +#endif break; } } @@ -556,9 +601,16 @@ Driver_Mesh::Status DriverCGNS_Write::Perform() // try to extract type of boundary condition from the group name string name = group->GetStoreName(); CGNS_ENUMT( BCType_t ) bcType = getBCType( name ); - while ( !groupNames.insert( name ).second ) - name = (SMESH_Comment( "Group_") << groupNames.size()); - + if ( !groupNames.insert( name ).second ) // assure name uniqueness + { + int index = 1; + string newName; + do { + newName = SMESH_Comment( name ) << "_" << index++; + } + while ( !groupNames.insert( newName ).second ); + name = newName; + } // write IDs of elements vector< cgsize_t > pnts; pnts.reserve( group->Extent() ); @@ -568,13 +620,15 @@ Driver_Mesh::Status DriverCGNS_Write::Perform() const SMDS_MeshElement* elem = elemIt->next(); pnts.push_back( cgnsID( elem, elem2cgIDByEntity[ elem->GetEntityType() ])); } + if ( pnts.size() == 0 ) + continue; // can't store empty group int iBC; if ( cg_boco_write( _fn, iBase, iZone, name.c_str(), bcType, CGNS_ENUMV( PointList ), pnts.size(), &pnts[0], &iBC) != CG_OK ) return addMessage( cg_get_error(), /*fatal = */true); // write BC location - if ( location != CGNS_ENUMV( Vertex )) + if ( location != CGNS_ENUMV( Vertex ) || meshDim == 1 ) { if ( cg_boco_gridlocation_write( _fn, iBase, iZone, iBC, location) != CG_OK ) return addMessage( cg_get_error(), /*fatal = */false); @@ -589,7 +643,7 @@ Driver_Mesh::Status DriverCGNS_Write::Perform() */ //================================================================================ -DriverCGNS_Write::DriverCGNS_Write(): _fn(0) +DriverCGNS_Write::DriverCGNS_Write(): _fn(0), _elementsByType( false ) { } diff --git a/src/DriverCGNS/DriverCGNS_Write.hxx b/src/DriverCGNS/DriverCGNS_Write.hxx index e427f9754..fd0ba2239 100644 --- a/src/DriverCGNS/DriverCGNS_Write.hxx +++ b/src/DriverCGNS/DriverCGNS_Write.hxx @@ -45,9 +45,16 @@ public: virtual Status Perform(); + // to export elements either in the order of their IDs or by geometric type + void SetElementsByType( bool isByType ) { _elementsByType = isByType; } + private: int _fn; //!< file index + + // if true all elements of same geometry are exported at ones, + // else elements are exported in order of their IDs + bool _elementsByType; }; #endif diff --git a/src/DriverMED/DriverMED_Family.cxx b/src/DriverMED/DriverMED_Family.cxx index 7954df08c..b758617e9 100644 --- a/src/DriverMED/DriverMED_Family.cxx +++ b/src/DriverMED/DriverMED_Family.cxx @@ -93,7 +93,7 @@ DriverMED_Family return myType; } -const std::set< SMDSAbs_ElementType >& +const ElemTypeSet& DriverMED_Family ::GetTypes() const { diff --git a/src/DriverMED/DriverMED_Family.h b/src/DriverMED/DriverMED_Family.h index 1325617f1..c71ea7254 100644 --- a/src/DriverMED/DriverMED_Family.h +++ b/src/DriverMED/DriverMED_Family.h @@ -36,6 +36,7 @@ #include "SMESHDS_SubMesh.hxx" #include "MED_Common.hxx" +#include #include #include #include @@ -58,10 +59,11 @@ #define NIG_BALL_FAMILY INT_MAX-5 #define NIG_GROUP_PREFIX "NOT_IN_GRP" -typedef std::list DriverMED_FamilyPtrList; -typedef std::map SMESHDS_SubMeshPtrMap; -typedef std::list SMESHDS_GroupBasePtrList; -typedef std::set ElementsSet; +typedef std::list DriverMED_FamilyPtrList; +typedef std::map SMESHDS_SubMeshPtrMap; +typedef std::list SMESHDS_GroupBasePtrList; +typedef std::set ElementsSet; +typedef boost::container::flat_set< SMDSAbs_ElementType > ElemTypeSet; class MESHDRIVERMED_EXPORT DriverMED_Family { @@ -113,7 +115,7 @@ class MESHDRIVERMED_EXPORT DriverMED_Family void SetType(const SMDSAbs_ElementType theType); SMDSAbs_ElementType GetType(); - const std::set< SMDSAbs_ElementType >& GetTypes() const; + const ElemTypeSet& GetTypes() const; bool MemberOf(std::string theGroupName) const; @@ -126,9 +128,8 @@ class MESHDRIVERMED_EXPORT DriverMED_Family //! Split on some parts (families) on the basis of the elements type. static - DriverMED_FamilyPtrList - SplitByType(SMESHDS_SubMesh* theSubMesh, - const int theId); + DriverMED_FamilyPtrList SplitByType(SMESHDS_SubMesh* theSubMesh, + const int theId); /*! Remove from elements, common with , @@ -143,12 +144,12 @@ class MESHDRIVERMED_EXPORT DriverMED_Family private: - int myId; - SMDSAbs_ElementType myType; - ElementsSet myElements; - MED::TStringSet myGroupNames; - int myGroupAttributVal; - std::set myTypes; // Issue 0020576 + int myId; + SMDSAbs_ElementType myType; + ElementsSet myElements; + MED::TStringSet myGroupNames; + int myGroupAttributVal; + ElemTypeSet myTypes; // Issue 0020576 }; #endif diff --git a/src/DriverMED/DriverMED_R_SMESHDS_Mesh.cxx b/src/DriverMED/DriverMED_R_SMESHDS_Mesh.cxx index 49ac9c892..b8d73352b 100644 --- a/src/DriverMED/DriverMED_R_SMESHDS_Mesh.cxx +++ b/src/DriverMED/DriverMED_R_SMESHDS_Mesh.cxx @@ -493,6 +493,7 @@ Driver_Mesh::Status DriverMED_R_SMESHDS_Mesh::Perform() case ePYRA13: aNbNodes = 13; break; case ePENTA6: aNbNodes = 6; break; case ePENTA15: aNbNodes = 15; break; + case ePENTA18: aNbNodes = 18; break; case eHEXA8: aNbNodes = 8; break; case eHEXA20: aNbNodes = 20; break; case eHEXA27: aNbNodes = 27; break; @@ -811,6 +812,41 @@ Driver_Mesh::Status DriverMED_R_SMESHDS_Mesh::Perform() isRenum = anIsElemNum; } break; + case ePENTA18: + aNbNodes = 18; + if(anIsElemNum) + anElement = myMesh->AddVolumeWithID(aNodeIds[0], aNodeIds[1], + aNodeIds[2], aNodeIds[3], + aNodeIds[4], aNodeIds[5], + aNodeIds[6], aNodeIds[7], + aNodeIds[8], aNodeIds[9], + aNodeIds[10], aNodeIds[11], + aNodeIds[12], aNodeIds[13], + aNodeIds[14], aNodeIds[15], + aNodeIds[16], aNodeIds[17], + aCellInfo->GetElemNum(iElem)); + if (!anElement) { + anElement = myMesh->AddVolume(FindNode(myMesh,aNodeIds[0]), + FindNode(myMesh,aNodeIds[1]), + FindNode(myMesh,aNodeIds[2]), + FindNode(myMesh,aNodeIds[3]), + FindNode(myMesh,aNodeIds[4]), + FindNode(myMesh,aNodeIds[5]), + FindNode(myMesh,aNodeIds[6]), + FindNode(myMesh,aNodeIds[7]), + FindNode(myMesh,aNodeIds[8]), + FindNode(myMesh,aNodeIds[9]), + FindNode(myMesh,aNodeIds[10]), + FindNode(myMesh,aNodeIds[11]), + FindNode(myMesh,aNodeIds[12]), + FindNode(myMesh,aNodeIds[13]), + FindNode(myMesh,aNodeIds[14]), + FindNode(myMesh,aNodeIds[15]), + FindNode(myMesh,aNodeIds[16]), + FindNode(myMesh,aNodeIds[17])); + isRenum = anIsElemNum; + } + break; case eHEXA8: aNbNodes = 8; if(anIsElemNum) @@ -1056,8 +1092,8 @@ list DriverMED_R_SMESHDS_Mesh::GetGroupNamesAndTypes() set::const_iterator aGrNamesIter = aGroupNames.begin(); for (; aGrNamesIter != aGroupNames.end(); aGrNamesIter++) { - const set< SMDSAbs_ElementType >& types = aFamily->GetTypes(); - set< SMDSAbs_ElementType >::const_iterator type = types.begin(); + const ElemTypeSet& types = aFamily->GetTypes(); + ElemTypeSet::const_iterator type = types.begin(); for ( ; type != types.end(); ++type ) { TNameAndType aNameAndType = make_pair( *aGrNamesIter, *type ); @@ -1073,28 +1109,51 @@ list DriverMED_R_SMESHDS_Mesh::GetGroupNamesAndTypes() void DriverMED_R_SMESHDS_Mesh::GetGroup(SMESHDS_Group* theGroup) { - string aGroupName (theGroup->GetStoreName()); + TFamilyVec * famVecPtr; + + if ( myGroups2FamiliesMap.IsEmpty() ) // PAL23514 + { + TFamilyVec famVector( 1 ); + map::iterator famIter = myFamilies.begin(); + for ( ; famIter != myFamilies.end(); famIter++ ) + { + DriverMED_FamilyPtr family = famIter->second; + const MED::TStringSet& groups = family->GetGroupNames(); + famVector[ 0 ] = family; + MED::TStringSet::const_iterator grpIter = groups.begin(); + for ( ; grpIter != groups.end(); ++grpIter ) + { + TCollection_AsciiString groupName = grpIter->c_str(); + if (( famVecPtr = myGroups2FamiliesMap.ChangeSeek( groupName ))) + famVecPtr->push_back( family ); + else + myGroups2FamiliesMap.Bind( groupName, famVector ); + } + } + } + + const char* aGroupName = theGroup->GetStoreName(); if(MYDEBUG) MESSAGE("Get Group " << aGroupName); - map::iterator aFamsIter = myFamilies.begin(); - for (; aFamsIter != myFamilies.end(); aFamsIter++) + if (( famVecPtr = myGroups2FamiliesMap.ChangeSeek( aGroupName ))) { - DriverMED_FamilyPtr aFamily = (*aFamsIter).second; - if (aFamily->GetTypes().count( theGroup->GetType() ) && aFamily->MemberOf(aGroupName)) + for ( size_t i = 0; i < famVecPtr->size(); ++i ) { - const ElementsSet& anElements = aFamily->GetElements(); - ElementsSet::const_iterator anElemsIter = anElements.begin(); - for (; anElemsIter != anElements.end(); anElemsIter++) + DriverMED_FamilyPtr aFamily = (*famVecPtr)[i]; + if ( aFamily->GetTypes().count( theGroup->GetType() )) { - const SMDS_MeshElement * element = *anElemsIter; - if ( element->GetType() == theGroup->GetType() ) // Issue 0020576 - theGroup->SMDSGroup().Add(element); + const ElementsSet& anElements = aFamily->GetElements(); + ElementsSet::const_iterator anElemsIter = anElements.begin(); + for (; anElemsIter != anElements.end(); anElemsIter++) + { + const SMDS_MeshElement * element = *anElemsIter; + if ( element->GetType() == theGroup->GetType() ) // Issue 0020576 + theGroup->SMDSGroup().Add(element); + } + int aGroupAttrVal = aFamily->GetGroupAttributVal(); + if( aGroupAttrVal != 0 ) + theGroup->SetColorGroup(aGroupAttrVal); } - int aGroupAttrVal = aFamily->GetGroupAttributVal(); - if( aGroupAttrVal != 0) - theGroup->SetColorGroup(aGroupAttrVal); -// if ( element ) -- Issue 0020576 -// theGroup->SetType( theGroup->SMDSGroup().GetType() ); } } } diff --git a/src/DriverMED/DriverMED_R_SMESHDS_Mesh.h b/src/DriverMED/DriverMED_R_SMESHDS_Mesh.h index bd8fa80b0..ba7994e42 100644 --- a/src/DriverMED/DriverMED_R_SMESHDS_Mesh.h +++ b/src/DriverMED/DriverMED_R_SMESHDS_Mesh.h @@ -36,11 +36,16 @@ #include #include +#include +#include + class SMESHDS_Mesh; class SMESHDS_Group; class SMESHDS_SubMesh; -typedef std::pair< std::string, SMDSAbs_ElementType > TNameAndType; +typedef std::vector< DriverMED_FamilyPtr > TFamilyVec; +typedef std::pair< std::string, SMDSAbs_ElementType > TNameAndType; +typedef NCollection_DataMap< TCollection_AsciiString, TFamilyVec > TName2Falilies; class MESHDRIVERMED_EXPORT DriverMED_R_SMESHDS_Mesh: public Driver_SMESHDS_Mesh { @@ -56,9 +61,9 @@ class MESHDRIVERMED_EXPORT DriverMED_R_SMESHDS_Mesh: public Driver_SMESHDS_Mesh void SetMeshName(std::string theMeshName); private: - std::string myMeshName; + std::string myMeshName; std::map myFamilies; - + TName2Falilies myGroups2FamiliesMap; }; #endif diff --git a/src/DriverMED/DriverMED_W_Field.cxx b/src/DriverMED/DriverMED_W_Field.cxx index 475730607..45bf8c3b9 100644 --- a/src/DriverMED/DriverMED_W_Field.cxx +++ b/src/DriverMED/DriverMED_W_Field.cxx @@ -393,6 +393,7 @@ namespace DriverMED // Implemetation of fuctions declared in DriverMED.hxx theVec[ SMDSEntity_TriQuad_Hexa ] = MED::eHEXA27 ; theVec[ SMDSEntity_Penta ] = MED::ePENTA6 ; theVec[ SMDSEntity_Quad_Penta ] = MED::ePENTA15 ; + theVec[ SMDSEntity_BiQuad_Penta ] = MED::ePENTA18 ; theVec[ SMDSEntity_Hexagonal_Prism ] = MED::eOCTA12 ; theVec[ SMDSEntity_Polyhedra ] = MED::ePOLYEDRE; //theVec[ SMDSEntity_Quad_Polyhedra ] = MED::ePOLYEDRE; // !! diff --git a/src/DriverMED/DriverMED_W_SMESHDS_Mesh.cxx b/src/DriverMED/DriverMED_W_SMESHDS_Mesh.cxx index 552a21417..55e80fbfd 100644 --- a/src/DriverMED/DriverMED_W_SMESHDS_Mesh.cxx +++ b/src/DriverMED/DriverMED_W_SMESHDS_Mesh.cxx @@ -677,7 +677,11 @@ Driver_Mesh::Status DriverMED_W_SMESHDS_Mesh::Perform() SMDSAbs_Volume)); aTElemTypeDatas.push_back( TElemTypeData(anEntity, ePENTA15, - nbElemInfo.NbPrisms( ORDER_QUADRATIC ), + nbElemInfo.NbQuadPrisms(), + SMDSAbs_Volume)); + aTElemTypeDatas.push_back( TElemTypeData(anEntity, + ePENTA18, + nbElemInfo.NbBiQuadPrisms(), SMDSAbs_Volume)); aTElemTypeDatas.push_back( TElemTypeData(anEntity, eHEXA8, @@ -729,6 +733,13 @@ Driver_Mesh::Status DriverMED_W_SMESHDS_Mesh::Perform() continue; } + // build map of family numbers for this type + if ( !isElemFamMapBuilt[ aElemTypeData->_smdsType ]) + { + fillElemFamilyMap( anElemFamMap, aFamilies, aElemTypeData->_smdsType ); + isElemFamMapBuilt[ aElemTypeData->_smdsType ] = true; + } + // iterator on elements of a current type SMDS_ElemIteratorPtr elemIterator; int iElem = 0; @@ -802,7 +813,7 @@ Driver_Mesh::Status DriverMED_W_SMESHDS_Mesh::Perform() else if (aElemTypeData->_geomType == ePOLYEDRE ) { elemIterator = myMesh->elementGeomIterator( SMDSGeom_POLYHEDRA ); - + if ( nbPolyhedronNodes == 0 ) { // Count nb of nodes while ( elemIterator->more() ) { @@ -879,13 +890,6 @@ Driver_Mesh::Status DriverMED_W_SMESHDS_Mesh::Perform() // allocate data arrays PBallInfo aBallInfo = myMed->CrBallInfo( aMeshInfo, aElemTypeData->_nbElems ); - // build map of family numbers for this type - if ( !isElemFamMapBuilt[ aElemTypeData->_smdsType ]) - { - fillElemFamilyMap( anElemFamMap, aFamilies, aElemTypeData->_smdsType ); - isElemFamMapBuilt[ aElemTypeData->_smdsType ] = true; - } - elemIterator = myMesh->elementsIterator( SMDSAbs_Ball ); while ( elemIterator->more() ) { @@ -917,7 +921,6 @@ Driver_Mesh::Status DriverMED_W_SMESHDS_Mesh::Perform() { // Treat standard types // --------------------- - // allocate data arrays PCellInfo aCellInfo = myMed->CrCellInfo( aMeshInfo, aElemTypeData->_entity, @@ -926,13 +929,6 @@ Driver_Mesh::Status DriverMED_W_SMESHDS_Mesh::Perform() theConnMode, theIsElemNum, theIsElemNames); - // build map of family numbers for this type - if ( !isElemFamMapBuilt[ aElemTypeData->_smdsType ]) - { - //cout << " fillElemFamilyMap()" << endl; - fillElemFamilyMap( anElemFamMap, aFamilies, aElemTypeData->_smdsType ); - isElemFamMapBuilt[ aElemTypeData->_smdsType ] = true; - } TInt aNbNodes = MED::GetNbNodes(aElemTypeData->_geomType); elemIterator = myMesh->elementsIterator( aElemTypeData->_smdsType ); @@ -967,10 +963,7 @@ Driver_Mesh::Status DriverMED_W_SMESHDS_Mesh::Perform() // store data in a file myMed->SetCellInfo(aCellInfo); } - } // loop on geom types - - } catch(const std::exception& exc) { INFOS("The following exception was caught:\n\t"< PElemNum; //--------------------------------------------------------------- - //! Define a parent class for all MED entities that describes mesh entites such as nodes and cells. + //! Define a parent class for all MED entities that describes mesh entities such as nodes and cells. struct MEDWRAPPER_EXPORT TElemInfo: virtual TBase { PMeshInfo myMeshInfo; //!< A reference to correspondig MED Mesh @@ -219,7 +219,7 @@ namespace MED //! Defines if the mesh elements are named EBooleen myIsElemNames; - //! Let know if the mesh elements havew names + //! Let know if the mesh elements have names EBooleen IsElemNames() const { return myIsElemNames; } //! Contains sequence of the names for the mesh elements @@ -1041,7 +1041,7 @@ namespace MED void SetGrilleStructure(TInt theAxis,TInt theNb); /*! - *Defines sequence MED Family indexes for corresponding mesh entites + *Defines sequence MED Family indexes for corresponding mesh entities */ TElemNum myFamNum; //! Get number of a MED FAMILY by order number of the mesh element @@ -1050,7 +1050,7 @@ namespace MED void SetFamNum(TInt theId, TInt theVal); /*! - *Defines sequence MED Family indexes for sub entites + *Defines sequence MED Family indexes for sub entities */ TElemNum myFamSubNum; //! Get number of a MED FAMILY by order number of sub element diff --git a/src/MEDWrapper/MED_TStructures.hxx b/src/MEDWrapper/MED_TStructures.hxx index b687ce369..d4c708c16 100644 --- a/src/MEDWrapper/MED_TStructures.hxx +++ b/src/MEDWrapper/MED_TStructures.hxx @@ -28,7 +28,7 @@ #ifdef WIN32 #pragma warning(disable:4250) #endif - +#include namespace MED { //--------------------------------------------------------------- diff --git a/src/OBJECT/SMESH_Actor.cxx b/src/OBJECT/SMESH_Actor.cxx index 43e4bca32..6bd4e2c62 100644 --- a/src/OBJECT/SMESH_Actor.cxx +++ b/src/OBJECT/SMESH_Actor.cxx @@ -279,6 +279,7 @@ SMESH_ActorDef::SMESH_ActorDef() aFilter->RegisterCellsWithType(VTK_QUADRATIC_HEXAHEDRON); aFilter->RegisterCellsWithType(VTK_TRIQUADRATIC_HEXAHEDRON); aFilter->RegisterCellsWithType(VTK_QUADRATIC_WEDGE); + aFilter->RegisterCellsWithType(VTK_BIQUADRATIC_QUADRATIC_WEDGE); aFilter->RegisterCellsWithType(VTK_QUADRATIC_PYRAMID); aFilter->RegisterCellsWithType(VTK_CONVEX_POINT_SET); aFilter->RegisterCellsWithType(VTK_POLYHEDRON); @@ -310,6 +311,7 @@ SMESH_ActorDef::SMESH_ActorDef() aFilter->RegisterCellsWithType(VTK_QUADRATIC_HEXAHEDRON); aFilter->RegisterCellsWithType(VTK_TRIQUADRATIC_HEXAHEDRON); aFilter->RegisterCellsWithType(VTK_QUADRATIC_WEDGE); + aFilter->RegisterCellsWithType(VTK_BIQUADRATIC_QUADRATIC_WEDGE); aFilter->RegisterCellsWithType(VTK_QUADRATIC_PYRAMID); aFilter->RegisterCellsWithType(VTK_CONVEX_POINT_SET); aFilter->RegisterCellsWithType(VTK_POLYHEDRON); @@ -842,11 +844,9 @@ void SMESH_ActorDef::SetControlMode( eControl theMode, bool theCheckEntityMode ) break; } case eLength2D: - { myFunctor.reset(new SMESH::Controls::Length2D()); myControlActor = my2DActor; break; - } case eFreeBorders: myFunctor.reset(new SMESH::Controls::FreeBorders()); myControlActor = my1DActor; @@ -956,6 +956,14 @@ void SMESH_ActorDef::SetControlMode( eControl theMode, bool theCheckEntityMode ) myControlActor = my3DActor; break; } + case eDeflection2D: + { + SMESH::Controls::Deflection2D* aControl = new SMESH::Controls::Deflection2D(); + aControl->SetPrecision( myControlsPrecision ); + myFunctor.reset( aControl ); + myControlActor = my2DActor; + break; + } case eBareBorderVolume: { myFunctor.reset(new SMESH::Controls::BareBorderVolume()); @@ -1430,6 +1438,10 @@ double* SMESH_ActorDef::GetNodeCoord(int theObjID) return myPickableActor->GetNodeCoord(theObjID); } +int SMESH_ActorDef::GetNodeVtkId(int theObjID) +{ + return myPickableActor->GetNodeVtkId(theObjID); +} int SMESH_ActorDef::GetElemObjId(int theVtkID) { @@ -1683,6 +1695,7 @@ void SMESH_ActorDef::SetEntityMode(unsigned int theMode) aFilter->RegisterCellsWithType(VTK_TRIQUADRATIC_HEXAHEDRON); aFilter->RegisterCellsWithType(VTK_QUADRATIC_PYRAMID); aFilter->RegisterCellsWithType(VTK_QUADRATIC_WEDGE); + aFilter->RegisterCellsWithType(VTK_BIQUADRATIC_QUADRATIC_WEDGE); aFilter->RegisterCellsWithType(VTK_CONVEX_POINT_SET); aFilter->RegisterCellsWithType(VTK_POLYHEDRON); @@ -1696,6 +1709,7 @@ void SMESH_ActorDef::SetEntityMode(unsigned int theMode) aHltFilter->RegisterCellsWithType(VTK_QUADRATIC_HEXAHEDRON); aHltFilter->RegisterCellsWithType(VTK_TRIQUADRATIC_HEXAHEDRON); aHltFilter->RegisterCellsWithType(VTK_QUADRATIC_WEDGE); + aHltFilter->RegisterCellsWithType(VTK_BIQUADRATIC_QUADRATIC_WEDGE); aHltFilter->RegisterCellsWithType(VTK_QUADRATIC_PYRAMID); aHltFilter->RegisterCellsWithType(VTK_CONVEX_POINT_SET); aHltFilter->RegisterCellsWithType(VTK_POLYHEDRON); diff --git a/src/OBJECT/SMESH_Actor.h b/src/OBJECT/SMESH_Actor.h index f49d55cbb..e8818e4d5 100644 --- a/src/OBJECT/SMESH_Actor.h +++ b/src/OBJECT/SMESH_Actor.h @@ -141,7 +141,7 @@ class SMESHOBJECT_EXPORT SMESH_Actor: public SALOME_Actor virtual void SetFacesOrientation3DVectors(bool theState) = 0; virtual bool GetFacesOrientation3DVectors() = 0; - enum eControl{eNone, eLength, eLength2D, eFreeBorders, eFreeEdges, eFreeNodes, + enum eControl{eNone, eLength, eLength2D, eDeflection2D, eFreeBorders, eFreeEdges, eFreeNodes, eFreeFaces, eMultiConnection, eArea, eTaper, eAspectRatio, eMinimumAngle, eWarping, eSkew, eAspectRatio3D, eMultiConnection2D, eVolume3D, eMaxElementLength2D, eMaxElementLength3D, eBareBorderFace, eBareBorderVolume, diff --git a/src/OBJECT/SMESH_ActorDef.h b/src/OBJECT/SMESH_ActorDef.h index dd8879ec6..3b9d9c68f 100644 --- a/src/OBJECT/SMESH_ActorDef.h +++ b/src/OBJECT/SMESH_ActorDef.h @@ -150,6 +150,7 @@ class SMESH_ActorDef : public SMESH_Actor virtual int GetNodeObjId(int theVtkID); virtual double* GetNodeCoord(int theObjID); + virtual int GetNodeVtkId(int theObjID); virtual int GetElemObjId(int theVtkID); virtual vtkCell* GetElemCell(int theObjID); diff --git a/src/OBJECT/SMESH_DeviceActor.cxx b/src/OBJECT/SMESH_DeviceActor.cxx index 2f6ccd06f..6ef8c4d61 100644 --- a/src/OBJECT/SMESH_DeviceActor.cxx +++ b/src/OBJECT/SMESH_DeviceActor.cxx @@ -37,6 +37,7 @@ #include #include #include +#include // VTK Includes #include @@ -94,8 +95,8 @@ SMESH_DeviceActor myMapper = VTKViewer_PolyDataMapper::New(); myPlaneCollection = vtkPlaneCollection::New(); - vtkMapper::GetResolveCoincidentTopologyPolygonOffsetParameters(myPolygonOffsetFactor, - myPolygonOffsetUnits); + VTKViewer_Actor::GetDefaultPolygonOffsetParameters(myPolygonOffsetFactor, + myPolygonOffsetUnits); myMapper->UseLookupTableScalarRangeOn(); myMapper->SetColorModeToMapScalars(); @@ -860,6 +861,12 @@ SMESH_DeviceActor return aCoord; } +int +SMESH_DeviceActor +::GetNodeVtkId(int theObjID) +{ + return myVisualObj->GetNodeVTKId(theObjID); +} int SMESH_DeviceActor diff --git a/src/OBJECT/SMESH_DeviceActor.h b/src/OBJECT/SMESH_DeviceActor.h index 1b8ceb48e..30d7c8c42 100644 --- a/src/OBJECT/SMESH_DeviceActor.h +++ b/src/OBJECT/SMESH_DeviceActor.h @@ -70,6 +70,7 @@ class SMESHOBJECT_EXPORT SMESH_DeviceActor: public vtkLODActor{ virtual int GetNodeObjId(int theVtkID); virtual double* GetNodeCoord(int theObjID); + virtual int GetNodeVtkId(int theObjID); virtual int GetElemObjId(int theVtkID); virtual vtkCell* GetElemCell(int theObjID); diff --git a/src/SMDS/SMDSAbs_ElementType.hxx b/src/SMDS/SMDSAbs_ElementType.hxx index 10ee0d5e0..491f4f068 100644 --- a/src/SMDS/SMDSAbs_ElementType.hxx +++ b/src/SMDS/SMDSAbs_ElementType.hxx @@ -98,6 +98,7 @@ enum SMDSAbs_EntityType { SMDSEntity_TriQuad_Hexa, SMDSEntity_Penta, SMDSEntity_Quad_Penta, + SMDSEntity_BiQuad_Penta, SMDSEntity_Hexagonal_Prism, SMDSEntity_Polyhedra, SMDSEntity_Quad_Polyhedra, diff --git a/src/SMDS/SMDS_Downward.cxx b/src/SMDS/SMDS_Downward.cxx index ef666df7a..c4ead4dac 100644 --- a/src/SMDS/SMDS_Downward.cxx +++ b/src/SMDS/SMDS_Downward.cxx @@ -61,6 +61,7 @@ int SMDS_Downward::getCellDimension(unsigned char cellType) _cellDimension[VTK_TRIQUADRATIC_HEXAHEDRON] = 3; _cellDimension[VTK_WEDGE] = 3; _cellDimension[VTK_QUADRATIC_WEDGE] = 3; + _cellDimension[VTK_BIQUADRATIC_QUADRATIC_WEDGE] = 3; _cellDimension[VTK_PYRAMID] = 3; _cellDimension[VTK_QUADRATIC_PYRAMID] = 3; _cellDimension[VTK_HEXAGONAL_PRISM] = 3; diff --git a/src/SMDS/SMDS_Mesh.cxx b/src/SMDS/SMDS_Mesh.cxx index 7c8e66327..40caa2c88 100644 --- a/src/SMDS/SMDS_Mesh.cxx +++ b/src/SMDS/SMDS_Mesh.cxx @@ -1556,9 +1556,15 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolumeFromVtkIdsWithID(const std::vectorGetFreeID(); + SMDS_MeshVolume * v = + SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n6, n12, n23, n31, + n45, n56, n64, n14, n25, n36, n1245, n2356, n1346, ID); + if(v==NULL) myElementIDFactory->ReleaseID(ID); + return v; +} + +//======================================================================= +//function : AddVolumeWithID +//purpose : 2d order Pentahedron (prism) with 18 nodes +//======================================================================= +SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, + int n4, int n5, int n6, + int n12,int n23,int n31, + int n45,int n56,int n64, + int n14,int n25,int n36, + int n1245, int n2356, int n1346, int ID) +{ + //MESSAGE("AddVolumeWithID penta18 " << ID); + return SMDS_Mesh::AddVolumeWithID + ((SMDS_MeshNode*) myNodeIDFactory->MeshElement(n1) , + (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n2) , + (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n3) , + (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n4) , + (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n5) , + (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n6) , + (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n12), + (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n23), + (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n31), + (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n45), + (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n56), + (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n64), + (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n14), + (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n25), + (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n36), + (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n1245), + (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n2356), + (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n1346), + ID); +} + +//======================================================================= +//function : AddVolumeWithID +//purpose : 2d order Pentahedron (prism) with 18 nodes +//======================================================================= +SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1, + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3, + const SMDS_MeshNode * n4, + const SMDS_MeshNode * n5, + const SMDS_MeshNode * n6, + const SMDS_MeshNode * n12, + const SMDS_MeshNode * n23, + const SMDS_MeshNode * n31, + const SMDS_MeshNode * n45, + const SMDS_MeshNode * n56, + const SMDS_MeshNode * n64, + const SMDS_MeshNode * n14, + const SMDS_MeshNode * n25, + const SMDS_MeshNode * n36, + const SMDS_MeshNode * n1245, + const SMDS_MeshNode * n2356, + const SMDS_MeshNode * n1346, + int ID) +{ + //MESSAGE("AddVolumeWithID penta18 "<< ID); + if (!n1 || !n2 || !n3 || !n4 || !n5 || !n6 || !n12 || !n23 || + !n31 || !n45 || !n56 || !n64 || !n14 || !n25 || !n36 || !n1245 || !n2356 || !n1346) + return 0; + if(hasConstructionFaces()) { + // creation quadratic faces - not implemented + return 0; + } + // --- retrieve nodes ID + myNodeIds.resize(18); + myNodeIds[0] = n1->getVtkId(); + myNodeIds[1] = n2->getVtkId(); + myNodeIds[2] = n3->getVtkId(); + + myNodeIds[3] = n4->getVtkId(); + myNodeIds[4] = n5->getVtkId(); + myNodeIds[5] = n6->getVtkId(); + + myNodeIds[6] = n12->getVtkId(); + myNodeIds[7] = n23->getVtkId(); + myNodeIds[8] = n31->getVtkId(); + + myNodeIds[9] = n45->getVtkId(); + myNodeIds[10] = n56->getVtkId(); + myNodeIds[11] = n64->getVtkId(); + + myNodeIds[12] = n14->getVtkId(); + myNodeIds[13] = n25->getVtkId(); + myNodeIds[14] = n36->getVtkId(); + + myNodeIds[15] = n1245->getVtkId(); + myNodeIds[16] = n2356->getVtkId(); + myNodeIds[17] = n1346->getVtkId(); + + SMDS_VtkVolume *volvtk = myVolumePool->getNew(); + volvtk->init(myNodeIds, this); + if (!this->registerElement(ID,volvtk)) + { + this->myGrid->GetCellTypesArray()->SetValue(volvtk->getVtkId(), VTK_EMPTY_CELL); + myVolumePool->destroy(volvtk); + return 0; + } + adjustmyCellsCapacity(ID); + myCells[ID] = volvtk; + myInfo.myNbBiQuadPrisms++; + + // if (!registerElement(ID, volvtk)) { + // RemoveElement(volvtk, false); + // volvtk = NULL; + // } + return volvtk; +} + //======================================================================= //function : AddVolume diff --git a/src/SMDS/SMDS_Mesh.hxx b/src/SMDS/SMDS_Mesh.hxx index d1d0b1120..5adcd6d62 100644 --- a/src/SMDS/SMDS_Mesh.hxx +++ b/src/SMDS/SMDS_Mesh.hxx @@ -454,6 +454,53 @@ public: const SMDS_MeshNode * n25, const SMDS_MeshNode * n36); + // 2d order Pentahedron with 18 nodes + virtual SMDS_MeshVolume* AddVolumeWithID(int n1, int n2, int n3, + int n4, int n5, int n6, + int n12,int n23,int n31, + int n45,int n56,int n64, + int n14,int n25,int n36, + int n1245, int n2356, int n1346, + int ID); + virtual SMDS_MeshVolume* AddVolumeWithID(const SMDS_MeshNode * n1, + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3, + const SMDS_MeshNode * n4, + const SMDS_MeshNode * n5, + const SMDS_MeshNode * n6, + const SMDS_MeshNode * n12, + const SMDS_MeshNode * n23, + const SMDS_MeshNode * n31, + const SMDS_MeshNode * n45, + const SMDS_MeshNode * n56, + const SMDS_MeshNode * n64, + const SMDS_MeshNode * n14, + const SMDS_MeshNode * n25, + const SMDS_MeshNode * n36, + const SMDS_MeshNode * n1245, + const SMDS_MeshNode * n2356, + const SMDS_MeshNode * n1346, + int ID); + virtual SMDS_MeshVolume* AddVolume(const SMDS_MeshNode * n1, + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3, + const SMDS_MeshNode * n4, + const SMDS_MeshNode * n5, + const SMDS_MeshNode * n6, + const SMDS_MeshNode * n12, + const SMDS_MeshNode * n23, + const SMDS_MeshNode * n31, + const SMDS_MeshNode * n45, + const SMDS_MeshNode * n56, + const SMDS_MeshNode * n64, + const SMDS_MeshNode * n14, + const SMDS_MeshNode * n25, + const SMDS_MeshNode * n36, + const SMDS_MeshNode * n1245, + const SMDS_MeshNode * n2356, + const SMDS_MeshNode * n1346); + + // 2d oreder Hexahedrons with 20 nodes virtual SMDS_MeshVolume* AddVolumeWithID(int n1, int n2, int n3, int n4, int n5, int n6, int n7, int n8, @@ -654,7 +701,7 @@ public: int idnode4, int idnode5, int idnode6) const; const SMDS_MeshFace *FindFace(int idnode1, int idnode2, int idnode3, int idnode4, int idnode5, int idnode6, int idnode7, int idnode8) const; - const SMDS_MeshElement *FindElement(int IDelem) const; + virtual const SMDS_MeshElement * FindElement(int IDelem) const; static const SMDS_Mesh0DElement* Find0DElement(const SMDS_MeshNode * n); static const SMDS_BallElement* FindBall(const SMDS_MeshNode * n); static const SMDS_MeshEdge* FindEdge(const SMDS_MeshNode * n1, diff --git a/src/SMDS/SMDS_MeshCell.cxx b/src/SMDS/SMDS_MeshCell.cxx index 6b7f04e08..7175ae5d4 100644 --- a/src/SMDS/SMDS_MeshCell.cxx +++ b/src/SMDS/SMDS_MeshCell.cxx @@ -66,6 +66,7 @@ VTKCellType SMDS_MeshCell::toVtkType (SMDSAbs_EntityType smdsType) vtkTypes[ SMDSEntity_TriQuad_Hexa ] = VTK_TRIQUADRATIC_HEXAHEDRON; vtkTypes[ SMDSEntity_Penta ] = VTK_WEDGE; vtkTypes[ SMDSEntity_Quad_Penta ] = VTK_QUADRATIC_WEDGE; + vtkTypes[ SMDSEntity_BiQuad_Penta ] = VTK_BIQUADRATIC_QUADRATIC_WEDGE; vtkTypes[ SMDSEntity_Hexagonal_Prism ] = VTK_HEXAGONAL_PRISM; vtkTypes[ SMDSEntity_Polyhedra ] = VTK_POLYHEDRON; //vtkTypes[ SMDSEntity_Quad_Polyhedra ] = ; @@ -153,9 +154,13 @@ const std::vector< int >& SMDS_MeshCell::toVtkOrder(SMDSAbs_EntityType smdsType) toVtkInterlaces[SMDSEntity_Penta].assign( &ids[0], &ids[0]+6 ); } { - const int ids[] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14}; + const int ids[] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14}; // TODO: check toVtkInterlaces[SMDSEntity_Quad_Penta].assign( &ids[0], &ids[0]+15 ); } + { + const int ids[] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17};// TODO: check + toVtkInterlaces[SMDSEntity_BiQuad_Penta].assign( &ids[0], &ids[0]+18 ); + } { const int ids[] = {0,5,4,3,2,1,6,11,10,9,8,7}; toVtkInterlaces[SMDSEntity_Hexagonal_Prism].assign( &ids[0], &ids[0]+12 ); @@ -254,6 +259,10 @@ const std::vector& SMDS_MeshCell::reverseSmdsOrder(SMDSAbs_EntityType smdsT reverseInterlaces[SMDSEntity_Quad_Penta].assign( &ids[0], &ids[0]+15 ); } { + const int ids[] = {0,2,1,3,5,4, 8,7,6,11,10,9,12,14,13,15,16,17}; + reverseInterlaces[SMDSEntity_BiQuad_Penta].assign( &ids[0], &ids[0]+18 ); + } + { const int ids[] = {0,5,4,3,2,1,6,11,10,9,8,7}; reverseInterlaces[SMDSEntity_Hexagonal_Prism].assign( &ids[0], &ids[0]+12 ); } @@ -414,6 +423,7 @@ SMDSAbs_ElementType SMDS_MeshCell::toSmdsType(SMDSAbs_EntityType entityType) case SMDSEntity_TriQuad_Hexa: case SMDSEntity_Penta: case SMDSEntity_Quad_Penta: + case SMDSEntity_BiQuad_Penta: case SMDSEntity_Hexagonal_Prism: case SMDSEntity_Polyhedra: case SMDSEntity_Quad_Polyhedra: return SMDSAbs_Volume; diff --git a/src/SMDS/SMDS_MeshInfo.hxx b/src/SMDS/SMDS_MeshInfo.hxx index d8bcf90d5..250442335 100644 --- a/src/SMDS/SMDS_MeshInfo.hxx +++ b/src/SMDS/SMDS_MeshInfo.hxx @@ -29,6 +29,7 @@ #include "SMESH_SMDS.hxx" #include "SMDS_MeshElement.hxx" +#include class SMDS_EXPORT SMDS_MeshInfo { @@ -64,6 +65,8 @@ public: inline int NbPrisms (SMDSAbs_ElementOrder order = ORDER_ANY) const; inline int NbHexPrisms(SMDSAbs_ElementOrder order = ORDER_ANY) const; int NbTriQuadHexas() const { return myNbTriQuadHexas; } + int NbQuadPrisms() const { return myNbQuadPrisms; } + int NbBiQuadPrisms() const { return myNbBiQuadPrisms; } int NbPolyhedrons() const { return myNbPolyhedrons; } protected: @@ -94,7 +97,7 @@ private: int myNbTetras , myNbQuadTetras ; int myNbHexas , myNbQuadHexas, myNbTriQuadHexas; int myNbPyramids, myNbQuadPyramids; - int myNbPrisms , myNbQuadPrisms ; + int myNbPrisms , myNbQuadPrisms, myNbBiQuadPrisms; int myNbHexPrism; int myNbPolyhedrons; @@ -113,7 +116,7 @@ inline SMDS_MeshInfo::SMDS_MeshInfo(): myNbTetras (0), myNbQuadTetras (0), myNbHexas (0), myNbQuadHexas (0), myNbTriQuadHexas(0), myNbPyramids (0), myNbQuadPyramids(0), - myNbPrisms (0), myNbQuadPrisms (0), + myNbPrisms (0), myNbQuadPrisms (0), myNbBiQuadPrisms(0), myNbHexPrism (0), myNbPolyhedrons(0) { @@ -142,26 +145,30 @@ inline SMDS_MeshInfo::SMDS_MeshInfo(): // 15 * // 16 * // 17 * - // 18 * - // 19 * + // 18 * + // 19 // 20 * - // 21 * - // 22 * - // 23 * - // 24 * - // 25 - // 26 + // 21 + // 22 + // 23 + // 24 + // 25 * + // 26 * // 27 * + // 28 * + // 29 * + // 30 * + // 31 * // // So to have a unique index for each type basing on nb of nodes, we use a shift: myShift.resize(SMDSAbs_NbElementTypes, 0); - myShift[ SMDSAbs_Face ] = +15;// 3->18, 4->19, etc. + myShift[ SMDSAbs_Face ] = +22;// 3->25, 4->26, etc. myShift[ SMDSAbs_Edge ] = +14;// 2->16, 3->17 myShift[ SMDSAbs_0DElement ] = +2; // 1->3 myShift[ SMDSAbs_Ball ] = +1; // 1->2 - myNb.resize( index( SMDSAbs_Volume,27 ) + 1, NULL); + myNb.resize( index( SMDSAbs_Face,9 ) + 1, NULL); myNb[ index( SMDSAbs_Node,1 )] = & myNbNodes; myNb[ index( SMDSAbs_0DElement,1 )] = & myNb0DElements; @@ -185,6 +192,7 @@ inline SMDS_MeshInfo::SMDS_MeshInfo(): myNb[ index( SMDSAbs_Volume, 12)] = & myNbHexPrism; myNb[ index( SMDSAbs_Volume, 13)] = & myNbQuadPyramids; myNb[ index( SMDSAbs_Volume, 15)] = & myNbQuadPrisms; + myNb[ index( SMDSAbs_Volume, 18)] = & myNbBiQuadPrisms; myNb[ index( SMDSAbs_Volume, 20)] = & myNbQuadHexas; myNb[ index( SMDSAbs_Volume, 27)] = & myNbTriQuadHexas; } @@ -280,7 +288,7 @@ SMDS_MeshInfo::NbPyramids(SMDSAbs_ElementOrder order) const inline int // NbPrisms SMDS_MeshInfo::NbPrisms (SMDSAbs_ElementOrder order) const -{ return order == ORDER_ANY ? myNbPrisms+myNbQuadPrisms : order == ORDER_LINEAR ? myNbPrisms : myNbQuadPrisms; } +{ return order == ORDER_ANY ? myNbPrisms+myNbQuadPrisms+myNbBiQuadPrisms: order == ORDER_LINEAR ? myNbPrisms : myNbQuadPrisms+myNbBiQuadPrisms; } inline int // NbHexPrisms SMDS_MeshInfo::NbHexPrisms (SMDSAbs_ElementOrder order) const @@ -297,7 +305,7 @@ SMDS_MeshInfo::NbElements(SMDSAbs_ElementType type) const break; case SMDSAbs_Volume: nb = ( myNbTetras+ myNbPyramids+ myNbPrisms+ myNbHexas+ myNbHexPrism+ - myNbQuadTetras+ myNbQuadPyramids+ myNbQuadPrisms+ myNbQuadHexas+ myNbTriQuadHexas+ + myNbQuadTetras+ myNbQuadPyramids+ myNbQuadPrisms+ myNbBiQuadPrisms + myNbQuadHexas+ myNbTriQuadHexas+ myNbPolyhedrons ); break; case SMDSAbs_Face: @@ -345,6 +353,7 @@ SMDS_MeshInfo::NbEntities(SMDSAbs_EntityType type) const case SMDSEntity_TriQuad_Hexa: return myNbTriQuadHexas; case SMDSEntity_Penta: return myNbPrisms; case SMDSEntity_Quad_Penta: return myNbQuadPrisms; + case SMDSEntity_BiQuad_Penta: return myNbBiQuadPrisms; case SMDSEntity_Hexagonal_Prism: return myNbHexPrism; case SMDSEntity_Polyhedra: return myNbPolyhedrons; case SMDSEntity_0D: return myNb0DElements; @@ -383,7 +392,8 @@ SMDS_MeshInfo::NbElementsOfGeom(SMDSAbs_GeometryType geom) const myNbQuadHexas + myNbTriQuadHexas); case SMDSGeom_PENTA: return (myNbPrisms + - myNbQuadPrisms); + myNbQuadPrisms + + myNbBiQuadPrisms); case SMDSGeom_HEXAGONAL_PRISM: return myNbHexPrism; case SMDSGeom_POLYHEDRA: return myNbPolyhedrons; // Discrete: @@ -414,6 +424,7 @@ SMDS_MeshInfo::setNb(const SMDSAbs_EntityType geomType, const int nb) case SMDSEntity_Quad_Edge: myNbQuadEdges = nb; break; case SMDSEntity_Quad_Hexa: myNbQuadHexas = nb; break; case SMDSEntity_Quad_Penta: myNbQuadPrisms = nb; break; + case SMDSEntity_BiQuad_Penta: myNbBiQuadPrisms = nb; break; case SMDSEntity_Quad_Pyramid: myNbQuadPyramids = nb; break; case SMDSEntity_Quad_Quadrangle: myNbQuadQuadrangles = nb; break; case SMDSEntity_Quad_Tetra: myNbQuadTetras = nb; break; diff --git a/src/SMDS/SMDS_QuadraticVolumeOfNodes.cxx b/src/SMDS/SMDS_QuadraticVolumeOfNodes.cxx index 92da9c6f1..f9c689a17 100644 --- a/src/SMDS/SMDS_QuadraticVolumeOfNodes.cxx +++ b/src/SMDS/SMDS_QuadraticVolumeOfNodes.cxx @@ -381,6 +381,7 @@ SMDSAbs_EntityType SMDS_QuadraticVolumeOfNodes::GetEntityType() const case 10: aType = SMDSEntity_Quad_Tetra; break; case 13: aType = SMDSEntity_Quad_Pyramid; break; case 15: aType = SMDSEntity_Quad_Penta; break; + case 18: aType = SMDSEntity_BiQuad_Penta; break; case 20: default: aType = SMDSEntity_Quad_Hexa; break; } diff --git a/src/SMDS/SMDS_SetIterator.hxx b/src/SMDS/SMDS_SetIterator.hxx index e0b3c8b08..3402cbf6a 100644 --- a/src/SMDS/SMDS_SetIterator.hxx +++ b/src/SMDS/SMDS_SetIterator.hxx @@ -51,6 +51,11 @@ namespace SMDS { static VALUE value(VALUE_SET_ITERATOR it) { return (VALUE) it->second; } }; + template + struct PointerAccessor { + static VALUE value(VALUE_SET_ITERATOR it) { return (VALUE) &(*it); } + }; + /////////////////////////////////////////////////////////////////////////////// /// Filters of value pointed by iterator /////////////////////////////////////////////////////////////////////////////// diff --git a/src/SMDS/SMDS_VtkCellIterator.cxx b/src/SMDS/SMDS_VtkCellIterator.cxx index 2fc70ee87..a0f0d3784 100644 --- a/src/SMDS/SMDS_VtkCellIterator.cxx +++ b/src/SMDS/SMDS_VtkCellIterator.cxx @@ -115,6 +115,7 @@ SMDS_VtkCellIteratorToUNV::SMDS_VtkCellIteratorToUNV(SMDS_Mesh* mesh, int vtkCel break; } case SMDSEntity_Quad_Penta: + case SMDSEntity_BiQuad_Penta: //TODO: check { static int id[] = { 0, 8, 2, 7, 1, 6, 12, 14, 13, 3, 11, 5, 10, 4, 9 }; ids = id; diff --git a/src/SMDS/SMDS_VtkVolume.cxx b/src/SMDS/SMDS_VtkVolume.cxx index 8f66ff084..ecbcd928d 100644 --- a/src/SMDS/SMDS_VtkVolume.cxx +++ b/src/SMDS/SMDS_VtkVolume.cxx @@ -45,16 +45,17 @@ void SMDS_VtkVolume::init(const std::vector& nodeIds, SMDS_Mesh* mesh vtkIdType aType = VTK_TETRA; switch (nodeIds.size()) // cases are in order of usage frequency { - case 4: aType = VTK_TETRA; break; - case 8: aType = VTK_HEXAHEDRON; break; - case 5: aType = VTK_PYRAMID; break; - case 6: aType = VTK_WEDGE; break; - case 10: aType = VTK_QUADRATIC_TETRA; break; - case 20: aType = VTK_QUADRATIC_HEXAHEDRON; break; - case 13: aType = VTK_QUADRATIC_PYRAMID; break; - case 15: aType = VTK_QUADRATIC_WEDGE; break; - case 12: aType = VTK_HEXAGONAL_PRISM; break; - case 27: aType = VTK_TRIQUADRATIC_HEXAHEDRON;break; + case 4: aType = VTK_TETRA; break; + case 8: aType = VTK_HEXAHEDRON; break; + case 5: aType = VTK_PYRAMID; break; + case 6: aType = VTK_WEDGE; break; + case 10: aType = VTK_QUADRATIC_TETRA; break; + case 20: aType = VTK_QUADRATIC_HEXAHEDRON; break; + case 13: aType = VTK_QUADRATIC_PYRAMID; break; + case 15: aType = VTK_QUADRATIC_WEDGE; break; + case 18: aType = VTK_BIQUADRATIC_QUADRATIC_WEDGE; break; + case 12: aType = VTK_HEXAGONAL_PRISM; break; + case 27: aType = VTK_TRIQUADRATIC_HEXAHEDRON; break; default: aType = VTK_HEXAHEDRON; } myVtkID = mesh->getGrid()->InsertNextLinkedCell(aType, nodeIds.size(), (vtkIdType *) &nodeIds[0]); @@ -169,6 +170,7 @@ int SMDS_VtkVolume::NbFaces() const case VTK_WEDGE: case VTK_QUADRATIC_PYRAMID: case VTK_QUADRATIC_WEDGE: + case VTK_BIQUADRATIC_QUADRATIC_WEDGE: nbFaces = 5; break; case VTK_HEXAHEDRON: @@ -239,6 +241,7 @@ int SMDS_VtkVolume::NbEdges() const break; case VTK_WEDGE: case VTK_QUADRATIC_WEDGE: + case VTK_BIQUADRATIC_QUADRATIC_WEDGE: nbEdges = 9; break; case VTK_HEXAHEDRON: @@ -467,6 +470,7 @@ bool SMDS_VtkVolume::IsQuadratic() const case VTK_QUADRATIC_TETRA: case VTK_QUADRATIC_PYRAMID: case VTK_QUADRATIC_WEDGE: + case VTK_BIQUADRATIC_QUADRATIC_WEDGE: case VTK_QUADRATIC_HEXAHEDRON: case VTK_TRIQUADRATIC_HEXAHEDRON: return true; @@ -497,6 +501,7 @@ bool SMDS_VtkVolume::IsMediumNode(const SMDS_MeshNode* node) const rankFirstMedium = 5; // medium nodes are of rank 5 to 12 break; case VTK_QUADRATIC_WEDGE: + case VTK_BIQUADRATIC_QUADRATIC_WEDGE: rankFirstMedium = 6; // medium nodes are of rank 6 to 14 break; case VTK_QUADRATIC_HEXAHEDRON: @@ -532,11 +537,12 @@ int SMDS_VtkVolume::NbCornerNodes() const vtkIdType aVtkType = grid->GetCellType(myVtkID); switch (aVtkType) { - case VTK_QUADRATIC_TETRA: return 4; - case VTK_QUADRATIC_PYRAMID: return 5; - case VTK_QUADRATIC_WEDGE: return 6; + case VTK_QUADRATIC_TETRA: return 4; + case VTK_QUADRATIC_PYRAMID: return 5; + case VTK_QUADRATIC_WEDGE: + case VTK_BIQUADRATIC_QUADRATIC_WEDGE: return 6; case VTK_QUADRATIC_HEXAHEDRON: - case VTK_TRIQUADRATIC_HEXAHEDRON: return 8; + case VTK_TRIQUADRATIC_HEXAHEDRON: return 8; default:; } return NbNodes(); @@ -571,6 +577,9 @@ SMDSAbs_EntityType SMDS_VtkVolume::GetEntityType() const case VTK_QUADRATIC_WEDGE: aType = SMDSEntity_Quad_Penta; break; + case VTK_BIQUADRATIC_QUADRATIC_WEDGE: + aType = SMDSEntity_BiQuad_Penta; + break; case VTK_QUADRATIC_HEXAHEDRON: aType = SMDSEntity_Quad_Hexa; break; @@ -608,6 +617,7 @@ SMDSAbs_GeometryType SMDS_VtkVolume::GetGeomType() const break; case VTK_WEDGE: case VTK_QUADRATIC_WEDGE: + case VTK_BIQUADRATIC_QUADRATIC_WEDGE: aType = SMDSGeom_PENTA; break; case VTK_HEXAHEDRON: diff --git a/src/SMESH/SMESH_Algo.cxx b/src/SMESH/SMESH_Algo.cxx index c4fbb42cf..45c4a7f55 100644 --- a/src/SMESH/SMESH_Algo.cxx +++ b/src/SMESH/SMESH_Algo.cxx @@ -42,8 +42,6 @@ #include "SMESH_TypeDefs.hxx" #include "SMESH_subMesh.hxx" -#include - #include #include #include @@ -87,7 +85,7 @@ using namespace std; bool SMESH_Algo::Features::IsCompatible( const SMESH_Algo::Features& algo2 ) const { if ( _dim > algo2._dim ) return algo2.IsCompatible( *this ); - // algo2 is of highter dimension + // algo2 is of higher dimension if ( _outElemTypes.empty() || algo2._inElemTypes.empty() ) return false; bool compatible = true; diff --git a/src/SMESH/SMESH_Mesh.cxx b/src/SMESH/SMESH_Mesh.cxx index 71f07dcf2..f830b4ad2 100644 --- a/src/SMESH/SMESH_Mesh.cxx +++ b/src/SMESH/SMESH_Mesh.cxx @@ -1397,6 +1397,7 @@ void SMESH_Mesh::ExportMED(const char * file, bool theAllElemsToGroup) throw(SALOME_Exception) { + //MESSAGE("MED_VERSION:"<< theVersion); SMESH_TRY; DriverMED_W_SMESHDS_Mesh myWriter; @@ -1532,6 +1533,7 @@ void SMESH_Mesh::ExportUNV(const char * file, myWriter.SetMeshId(_id); // myWriter.SetGroups(_mapGroup); + // pass group names to SMESHDS if ( !meshPart ) { for ( map::iterator it = _mapGroup.begin(); it != _mapGroup.end(); it++ ) { @@ -1576,17 +1578,37 @@ void SMESH_Mesh::ExportSTL(const char * file, void SMESH_Mesh::ExportCGNS(const char * file, const SMESHDS_Mesh* meshDS, - const char * meshName) + const char * meshName, + const bool groupElemsByType) { int res = Driver_Mesh::DRS_FAIL; + + // pass group names to SMESHDS + for ( map::iterator it = _mapGroup.begin(); it != _mapGroup.end(); it++ ) { + SMESH_Group* group = it->second; + SMESHDS_GroupBase* groupDS = group->GetGroupDS(); + if ( groupDS ) { + string groupName = group->GetName(); + groupDS->SetStoreName( groupName.c_str() ); + } + } #ifdef WITH_CGNS + DriverCGNS_Write myWriter; myWriter.SetFile( file ); myWriter.SetMesh( const_cast( meshDS )); myWriter.SetMeshName( SMESH_Comment("Mesh_") << meshDS->GetPersistentId()); if ( meshName && meshName[0] ) myWriter.SetMeshName( meshName ); + myWriter.SetElementsByType( groupElemsByType ); res = myWriter.Perform(); + if ( res != Driver_Mesh::DRS_OK ) + { + SMESH_ComputeErrorPtr err = myWriter.GetError(); + if ( err && !err->IsOK() && !err->myComment.empty() ) + throw SALOME_Exception(("Export failed: " + err->myComment ).c_str() ); + } + #endif if ( res != Driver_Mesh::DRS_OK ) throw SALOME_Exception("Export failed"); @@ -1864,6 +1886,19 @@ int SMESH_Mesh::NbPrisms(SMDSAbs_ElementOrder order) const throw(SALOME_Exceptio return _myMeshDS->GetMeshInfo().NbPrisms(order); } +int SMESH_Mesh::NbQuadPrisms() const throw (SALOME_Exception) +{ + Unexpect aCatch(SalomeException); + return _myMeshDS->GetMeshInfo().NbQuadPrisms(); +} + +int SMESH_Mesh::NbBiQuadPrisms() const throw (SALOME_Exception) +{ + Unexpect aCatch(SalomeException); + return _myMeshDS->GetMeshInfo().NbBiQuadPrisms(); +} + + //================================================================================ /*! * \brief Return number of hexagonal prisms in the mesh @@ -2149,7 +2184,7 @@ ostream& SMESH_Mesh::Dump(ostream& save) save << clause << ".3) Faces in detail: " << endl; map ::iterator itF; for (itF = myFaceMap.begin(); itF != myFaceMap.end(); itF++) - save << "--> nb nodes: " << itF->first << " - nb elemens:\t" << itF->second << endl; + save << "--> nb nodes: " << itF->first << " - nb elements:\t" << itF->second << endl; } } save << ++clause << ") Total number of " << orderStr << " volumes:\t" << NbVolumes(order) << endl; @@ -2174,7 +2209,7 @@ ostream& SMESH_Mesh::Dump(ostream& save) save << clause << ".5) Volumes in detail: " << endl; map ::iterator itV; for (itV = myVolumesMap.begin(); itV != myVolumesMap.end(); itV++) - save << "--> nb nodes: " << itV->first << " - nb elemens:\t" << itV->second << endl; + save << "--> nb nodes: " << itV->first << " - nb elements:\t" << itV->second << endl; } } save << endl; diff --git a/src/SMESH/SMESH_Mesh.hxx b/src/SMESH/SMESH_Mesh.hxx index ee881f1fc..78681c396 100644 --- a/src/SMESH/SMESH_Mesh.hxx +++ b/src/SMESH/SMESH_Mesh.hxx @@ -265,7 +265,8 @@ class SMESH_EXPORT SMESH_Mesh const SMESHDS_Mesh* meshPart = 0) throw(SALOME_Exception); void ExportCGNS(const char * file, const SMESHDS_Mesh* mesh, - const char * meshName = 0); + const char * meshName = 0, + const bool groupElemsByType = false); void ExportGMF(const char * file, const SMESHDS_Mesh* mesh, bool withRequiredGroups = true ); @@ -294,6 +295,8 @@ class SMESH_EXPORT SMESH_Mesh int NbTriQuadraticHexas() const throw(SALOME_Exception); int NbPyramids(SMDSAbs_ElementOrder order = ORDER_ANY) const throw(SALOME_Exception); int NbPrisms(SMDSAbs_ElementOrder order = ORDER_ANY) const throw(SALOME_Exception); + int NbQuadPrisms() const throw(SALOME_Exception); + int NbBiQuadPrisms() const throw(SALOME_Exception); int NbHexagonalPrisms() const throw(SALOME_Exception); int NbPolyhedrons() const throw(SALOME_Exception); diff --git a/src/SMESH/SMESH_MeshEditor.cxx b/src/SMESH/SMESH_MeshEditor.cxx index c477e729e..4d7720381 100644 --- a/src/SMESH/SMESH_MeshEditor.cxx +++ b/src/SMESH/SMESH_MeshEditor.cxx @@ -46,8 +46,6 @@ #include "SMESH_OctreeNode.hxx" #include "SMESH_subMesh.hxx" -#include - #include "utilities.h" #include "chrono.hxx" @@ -98,6 +96,9 @@ #include #include +#include + +#include "SMESH_TryCatch.hxx" // include after OCCT headers! #define cast2Node(elem) static_cast( elem ) @@ -1914,6 +1915,7 @@ namespace break; case SMDSEntity_Penta: case SMDSEntity_Quad_Penta: + case SMDSEntity_BiQuad_Penta: connVariants = thePentaTo3; nbTet = 3; nbVariants = 6; break; default: @@ -9229,6 +9231,7 @@ int SMESH_MeshEditor::convertElemToQuadratic(SMESHDS_SubMesh * theSm, SMESH_MesherHelper& theHelper, const bool theForce3d) { + //MESSAGE("convertElemToQuadratic"); int nbElem = 0; if( !theSm ) return nbElem; @@ -9254,18 +9257,20 @@ int SMESH_MeshEditor::convertElemToQuadratic(SMESHDS_SubMesh * theSm, case SMDSEntity_Quad_Triangle: case SMDSEntity_Quad_Quadrangle: case SMDSEntity_Quad_Hexa: + case SMDSEntity_Quad_Penta: alreadyOK = !theHelper.GetIsBiQuadratic(); break; case SMDSEntity_BiQuad_Triangle: case SMDSEntity_BiQuad_Quadrangle: case SMDSEntity_TriQuad_Hexa: + case SMDSEntity_BiQuad_Penta: alreadyOK = theHelper.GetIsBiQuadratic(); hasCentralNodes = true; break; default: alreadyOK = true; } - // take into account already present modium nodes + // take into account already present medium nodes switch ( aType ) { case SMDSAbs_Volume: theHelper.AddTLinks( static_cast< const SMDS_MeshVolume* >( elem )); break; @@ -9332,6 +9337,8 @@ int SMESH_MeshEditor::convertElemToQuadratic(SMESHDS_SubMesh * theSm, NewElem = theHelper.AddVolume(nodes[0], nodes[1], nodes[2], nodes[3], nodes[4], id, theForce3d); break; case SMDSEntity_Penta: + case SMDSEntity_Quad_Penta: + case SMDSEntity_BiQuad_Penta: NewElem = theHelper.AddVolume(nodes[0], nodes[1], nodes[2], nodes[3], nodes[4], nodes[5], id, theForce3d); break; case SMDSEntity_Hexa: @@ -9362,6 +9369,7 @@ int SMESH_MeshEditor::convertElemToQuadratic(SMESHDS_SubMesh * theSm, void SMESH_MeshEditor::ConvertToQuadratic(const bool theForce3d, const bool theToBiQuad) { + //MESSAGE("ConvertToQuadratic "<< theForce3d << " " << theToBiQuad); SMESHDS_Mesh* meshDS = GetMeshDS(); SMESH_MesherHelper aHelper(*myMesh); @@ -9489,6 +9497,8 @@ void SMESH_MeshEditor::ConvertToQuadratic(const bool theForce3d, const bool theT { case SMDSEntity_Quad_Hexa: alreadyOK = !theToBiQuad; break; case SMDSEntity_TriQuad_Hexa: alreadyOK = theToBiQuad; break; + case SMDSEntity_Quad_Penta: alreadyOK = !theToBiQuad; break; + case SMDSEntity_BiQuad_Penta: alreadyOK = theToBiQuad; break; default: alreadyOK = true; } if ( alreadyOK ) @@ -9526,8 +9536,13 @@ void SMESH_MeshEditor::ConvertToQuadratic(const bool theForce3d, const bool theT nodes[3], nodes[4], id, theForce3d); break; case SMDSEntity_Penta: + case SMDSEntity_Quad_Penta: + case SMDSEntity_BiQuad_Penta: NewVolume = aHelper.AddVolume(nodes[0], nodes[1], nodes[2], nodes[3], nodes[4], nodes[5], id, theForce3d); + for ( size_t i = 15; i < nodes.size(); ++i ) // rm central nodes + if ( nodes[i]->NbInverseElements() == 0 ) + GetMeshDS()->RemoveFreeNode( nodes[i], /*sm=*/0, /*fromGroups=*/true ); break; case SMDSEntity_Hexagonal_Prism: default: @@ -12831,3 +12846,482 @@ void SMESH_MeshEditor::copyPosition( const SMDS_MeshNode* from, default:; } } + +namespace // utils for MakePolyLine +{ + //================================================================================ + /*! + * \brief Sequence of found points and a current point data + */ + struct Path + { + std::vector< gp_XYZ > myPoints; + double myLength; + + int mySrcPntInd; //!< start point index + const SMDS_MeshElement* myFace; + SMESH_NodeXYZ myNode1; + SMESH_NodeXYZ myNode2; + int myNodeInd1; + int myNodeInd2; + double myDot1; + double myDot2; + TIDSortedElemSet myElemSet, myAvoidSet; + + Path(): myLength(0.0), myFace(0) {} + + bool SetCutAtCorner( const SMESH_NodeXYZ& cornerNode, + const SMDS_MeshElement* face, + const gp_XYZ& plnNorm, + const gp_XYZ& plnOrig ); + + void AddPoint( const gp_XYZ& p ); + + bool Extend( const gp_XYZ& plnNorm, const gp_XYZ& plnOrig ); + + bool ReachSamePoint( const Path& other ); + + static void Remove( std::vector< Path > & paths, size_t& i ); + }; + + //================================================================================ + /*! + * \brief Return true if this Path meats another + */ + //================================================================================ + + bool Path::ReachSamePoint( const Path& other ) + { + return ( mySrcPntInd != other.mySrcPntInd && + myFace == other.myFace ); + } + + //================================================================================ + /*! + * \brief Remove a path from a vector + */ + //================================================================================ + + void Path::Remove( std::vector< Path > & paths, size_t& i ) + { + if ( paths.size() > 1 ) + { + size_t j = paths.size() - 1; // last item to be removed + if ( i < j ) + { + paths[ i ].myPoints.swap( paths[ j ].myPoints ); + paths[ i ].myLength = paths[ j ].myLength; + paths[ i ].mySrcPntInd = paths[ j ].mySrcPntInd; + paths[ i ].myFace = paths[ j ].myFace; + paths[ i ].myNode1 = paths[ j ].myNode1; + paths[ i ].myNode2 = paths[ j ].myNode2; + paths[ i ].myNodeInd1 = paths[ j ].myNodeInd1; + paths[ i ].myNodeInd2 = paths[ j ].myNodeInd2; + paths[ i ].myDot1 = paths[ j ].myDot1; + paths[ i ].myDot2 = paths[ j ].myDot2; + } + } + paths.pop_back(); + if ( i > 0 ) + --i; + } + + //================================================================================ + /*! + * \brief Store a point that is at a node of a face if the face is intersected by plane. + * Return false if the node is a sole intersection point of the face and the plane + */ + //================================================================================ + + bool Path::SetCutAtCorner( const SMESH_NodeXYZ& cornerNode, + const SMDS_MeshElement* face, + const gp_XYZ& plnNorm, + const gp_XYZ& plnOrig ) + { + if ( face == myFace ) + return false; + myNodeInd1 = face->GetNodeIndex( cornerNode._node ); + myNodeInd2 = ( myNodeInd1 + 1 ) % face->NbCornerNodes(); + int ind3 = ( myNodeInd1 + 2 ) % face->NbCornerNodes(); + myNode1.Set( face->GetNode( ind3 )); + myNode2.Set( face->GetNode( myNodeInd2 )); + + myDot1 = plnNorm * ( myNode1 - plnOrig ); + myDot2 = plnNorm * ( myNode2 - plnOrig ); + + bool ok = ( myDot1 * myDot2 < 0 ); + if ( !ok && myDot1 * myDot2 == 0 ) + { + ok = ( myDot1 != myDot2 ); + if ( ok && myFace ) + ok = ( myFace->GetNodeIndex(( myDot1 == 0 ? myNode1 : myNode2 )._node ) < 0 ); + } + if ( ok ) + { + myFace = face; + myDot1 = 0; + AddPoint( cornerNode ); + } + return ok; + } + + //================================================================================ + /*! + * \brief Store a point and update myLength + */ + //================================================================================ + + void Path::AddPoint( const gp_XYZ& p ) + { + if ( !myPoints.empty() ) + myLength += ( p - myPoints.back() ).Modulus(); + else + myLength = 0; + myPoints.push_back( p ); + } + + //================================================================================ + /*! + * \brief Try to find the next point + * \param [in] plnNorm - cutting plane normal + * \param [in] plnOrig - cutting plane origin + */ + //================================================================================ + + bool Path::Extend( const gp_XYZ& plnNorm, const gp_XYZ& plnOrig ) + { + int nodeInd3 = ( myNodeInd1 + 1 ) % myFace->NbCornerNodes(); + if ( myNodeInd2 == nodeInd3 ) + nodeInd3 = ( myNodeInd1 + 2 ) % myFace->NbCornerNodes(); + + SMESH_NodeXYZ node3 = myFace->GetNode( nodeInd3 ); + double dot3 = plnNorm * ( node3 - plnOrig ); + + if ( dot3 * myDot1 < 0. ) + { + myNode2 = node3; + myNodeInd2 = nodeInd3; + myDot2 = dot3; + } + else if ( dot3 * myDot2 < 0. ) + { + myNode1 = node3; + myNodeInd1 = nodeInd3; + myDot1 = dot3; + } + else if ( dot3 == 0. ) + { + SMDS_ElemIteratorPtr fIt = node3._node->GetInverseElementIterator(SMDSAbs_Face); + while ( fIt->more() ) + if ( SetCutAtCorner( node3, fIt->next(), plnNorm, plnOrig )) + return true; + return false; + } + else if ( myDot2 == 0. ) + { + SMESH_NodeXYZ node2 = myNode2; // copy as myNode2 changes in SetCutAtCorner() + SMDS_ElemIteratorPtr fIt = node2._node->GetInverseElementIterator(SMDSAbs_Face); + while ( fIt->more() ) + if ( SetCutAtCorner( node2, fIt->next(), plnNorm, plnOrig )) + return true; + return false; + } + + double r = Abs( myDot1 / ( myDot2 - myDot1 )); + AddPoint( myNode1 * ( 1 - r ) + myNode2 * r ); + + myAvoidSet.clear(); + myAvoidSet.insert( myFace ); + myFace = SMESH_MeshAlgos::FindFaceInSet( myNode1._node, myNode2._node, + myElemSet, myAvoidSet, + &myNodeInd1, &myNodeInd2 ); + return myFace; + } + + //================================================================================ + /*! + * \brief Compute a path between two points of PolySegment + */ + struct PolyPathCompute + { + SMESH_MeshEditor::TListOfPolySegments& mySegments; //!< inout PolySegment's + std::vector< Path >& myPaths; //!< path of each of segments to compute + SMESH_Mesh* myMesh; + mutable std::vector< std::string > myErrors; + + PolyPathCompute( SMESH_MeshEditor::TListOfPolySegments& theSegments, + std::vector< Path >& thePaths, + SMESH_Mesh* theMesh): + mySegments( theSegments ), + myPaths( thePaths ), + myMesh( theMesh ), + myErrors( theSegments.size() ) + { + } +#undef SMESH_CAUGHT +#define SMESH_CAUGHT myErrors[i] = + void operator() ( const int i ) const + { + SMESH_TRY; + const_cast< PolyPathCompute* >( this )->Compute( i ); + SMESH_CATCH( SMESH::returnError ); + } +#undef SMESH_CAUGHT + //================================================================================ + /*! + * \brief Compute a path of a given segment + */ + //================================================================================ + + void Compute( const int iSeg ) + { + SMESH_MeshEditor::PolySegment& polySeg = mySegments[ iSeg ]; + + // get a cutting plane + + gp_XYZ p1 = SMESH_NodeXYZ( polySeg.myNode1[0] ); + gp_XYZ p2 = SMESH_NodeXYZ( polySeg.myNode1[1] ); + if ( polySeg.myNode2[0] ) p1 = 0.5 * ( p1 + SMESH_NodeXYZ( polySeg.myNode2[0] )); + if ( polySeg.myNode2[1] ) p2 = 0.5 * ( p2 + SMESH_NodeXYZ( polySeg.myNode2[1] )); + + gp_XYZ plnNorm = ( p1 - p2 ) ^ polySeg.myVector.XYZ(); + gp_XYZ plnOrig = p2; + + // find paths connecting the 2 end points of polySeg + + std::vector< Path > paths; paths.reserve(10); + + // initialize paths + + for ( int iP = 0; iP < 2; ++iP ) // loop on the polySeg end points + { + Path path; + path.mySrcPntInd = iP; + size_t nbPaths = paths.size(); + + if ( polySeg.myNode2[ iP ] && polySeg.myNode2[ iP ] != polySeg.myNode1[ iP ] ) + { + while (( path.myFace = SMESH_MeshAlgos::FindFaceInSet( polySeg.myNode1[ iP ], + polySeg.myNode2[ iP ], + path.myElemSet, + path.myAvoidSet, + &path.myNodeInd1, + &path.myNodeInd2 ))) + { + path.myNode1.Set( polySeg.myNode1[ iP ]); + path.myNode2.Set( polySeg.myNode2[ iP ]); + path.myDot1 = plnNorm * ( path.myNode1 - plnOrig ); + path.myDot2 = plnNorm * ( path.myNode2 - plnOrig ); + path.myPoints.clear(); + path.AddPoint( 0.5 * ( path.myNode1 + path.myNode2 )); + path.myAvoidSet.insert( path.myFace ); + paths.push_back( path ); + } + if ( nbPaths == paths.size() ) + throw SALOME_Exception ( SMESH_Comment("No face edge found by point ") << iP+1 + << " in a PolySegment " << iSeg ); + } + else // an end point is at node + { + std::set nodes; + SMDS_ElemIteratorPtr fIt = polySeg.myNode1[ iP ]->GetInverseElementIterator(SMDSAbs_Face); + while ( fIt->more() ) + { + path.myPoints.clear(); + if ( path.SetCutAtCorner( polySeg.myNode1[ iP ], fIt->next(), plnNorm, plnOrig )) + { + if (( path.myDot1 * path.myDot2 != 0 ) || + ( nodes.insert( path.myDot1 == 0 ? path.myNode1._node : path.myNode2._node ).second )) + paths.push_back( path ); + } + } + } + + // look for a one-segment path + for ( size_t i = 0; i < nbPaths; ++i ) + for ( size_t j = nbPaths; j < paths.size(); ++j ) + if ( paths[i].myFace == paths[j].myFace ) + { + myPaths[ iSeg ].myPoints.push_back( paths[i].myPoints[0] ); + myPaths[ iSeg ].myPoints.push_back( paths[j].myPoints[0] ); + paths.clear(); + } + } + + // extend paths + + myPaths[ iSeg ].myLength = 1e100; + + while ( paths.size() >= 2 ) + { + for ( size_t i = 0; i < paths.size(); ++i ) + { + Path& path = paths[ i ]; + if ( !path.Extend( plnNorm, plnOrig ) || // path reached a mesh boundary + path.myLength > myPaths[ iSeg ].myLength ) // path is longer than others + { + Path::Remove( paths, i ); + continue; + } + + // join paths that reach same point + for ( size_t j = 0; j < paths.size(); ++j ) + { + if ( i != j && paths[i].ReachSamePoint( paths[j] )) + { + double distLast = ( paths[i].myPoints.back() - paths[j].myPoints.back() ).Modulus(); + double fullLength = ( paths[i].myLength + paths[j].myLength + distLast ); + if ( fullLength < myPaths[ iSeg ].myLength ) + { + myPaths[ iSeg ].myLength = fullLength; + std::vector< gp_XYZ > & allPoints = myPaths[ iSeg ].myPoints; + allPoints.swap( paths[i].myPoints ); + allPoints.insert( allPoints.end(), + paths[j].myPoints.rbegin(), + paths[j].myPoints.rend() ); + } + Path::Remove( paths, i ); + Path::Remove( paths, j ); + } + } + } + if ( !paths.empty() && (int) paths[0].myPoints.size() > myMesh->NbFaces() ) + throw SALOME_Exception(LOCALIZED( "Infinite loop in MakePolyLine()")); + } + + if ( myPaths[ iSeg ].myPoints.empty() ) + throw SALOME_Exception( SMESH_Comment("Can't find a full path for PolySegment #") << iSeg ); + + } // PolyPathCompute::Compute() + + }; // struct PolyPathCompute + +} // namespace + +//======================================================================= +//function : MakePolyLine +//purpose : Create a polyline consisting of 1D mesh elements each lying on a 2D element of +// the initial mesh +//======================================================================= + +void SMESH_MeshEditor::MakePolyLine( TListOfPolySegments& theSegments, + SMESHDS_Group* theGroup, + SMESH_ElementSearcher* theSearcher) +{ + std::vector< Path > segPaths( theSegments.size() ); // path of each of segments + + SMESH_ElementSearcher* searcher = theSearcher; + SMESHUtils::Deleter delSearcher; + if ( !searcher ) + { + searcher = SMESH_MeshAlgos::GetElementSearcher( *GetMeshDS() ); + delSearcher._obj = searcher; + } + + // get cutting planes + + std::vector< bool > isVectorOK( theSegments.size(), true ); + const double planarCoef = 0.333; // plane height in planar case + + for ( size_t iSeg = 0; iSeg < theSegments.size(); ++iSeg ) + { + PolySegment& polySeg = theSegments[ iSeg ]; + + gp_XYZ p1 = SMESH_NodeXYZ( polySeg.myNode1[0] ); + gp_XYZ p2 = SMESH_NodeXYZ( polySeg.myNode1[1] ); + if ( polySeg.myNode2[0] ) p1 = 0.5 * ( p1 + SMESH_NodeXYZ( polySeg.myNode2[0] )); + if ( polySeg.myNode2[1] ) p2 = 0.5 * ( p2 + SMESH_NodeXYZ( polySeg.myNode2[1] )); + + gp_XYZ plnNorm = ( p1 - p2 ) ^ polySeg.myVector.XYZ(); + + isVectorOK[ iSeg ] = ( plnNorm.Modulus() > std::numeric_limits::min() ); + if ( !isVectorOK[ iSeg ]) + { + gp_XYZ pMid = 0.5 * ( p1 + p2 ); + const SMDS_MeshElement* face; + polySeg.myMidProjPoint = searcher->Project( pMid, SMDSAbs_Face, &face ); + polySeg.myVector = polySeg.myMidProjPoint.XYZ() - pMid; + + gp_XYZ faceNorm; + SMESH_MeshAlgos::FaceNormal( face, faceNorm ); + + if ( polySeg.myVector.Magnitude() < Precision::Confusion() || + polySeg.myVector * faceNorm < Precision::Confusion() ) + { + polySeg.myVector = faceNorm; + polySeg.myMidProjPoint = pMid + faceNorm * ( p1 - p2 ).Modulus() * planarCoef; + } + } + else + { + polySeg.myVector = plnNorm ^ ( p1 - p2 ); + } + } + + // assure that inverse elements are constructed, avoid their concurrent building in threads + GetMeshDS()->nodesIterator()->next()->NbInverseElements(); + + // find paths + + PolyPathCompute algo( theSegments, segPaths, myMesh ); + OSD_Parallel::For( 0, theSegments.size(), algo, theSegments.size() == 1 ); + + for ( size_t iSeg = 0; iSeg < theSegments.size(); ++iSeg ) + if ( !algo.myErrors[ iSeg ].empty() ) + throw SALOME_Exception( algo.myErrors[ iSeg ].c_str() ); + + // create an 1D mesh + + const SMDS_MeshNode *n, *nPrev = 0; + SMESHDS_Mesh* mesh = GetMeshDS(); + + for ( size_t iSeg = 0; iSeg < theSegments.size(); ++iSeg ) + { + const Path& path = segPaths[iSeg]; + if ( path.myPoints.size() < 2 ) + continue; + + double tol = path.myLength / path.myPoints.size() / 1000.; + if ( !nPrev || ( SMESH_NodeXYZ( nPrev ) - path.myPoints[0] ).SquareModulus() > tol*tol ) + { + nPrev = mesh->AddNode( path.myPoints[0].X(), path.myPoints[0].Y(), path.myPoints[0].Z() ); + myLastCreatedNodes.Append( nPrev ); + } + for ( size_t iP = 1; iP < path.myPoints.size(); ++iP ) + { + n = mesh->AddNode( path.myPoints[iP].X(), path.myPoints[iP].Y(), path.myPoints[iP].Z() ); + myLastCreatedNodes.Append( n ); + + const SMDS_MeshElement* elem = mesh->AddEdge( nPrev, n ); + myLastCreatedElems.Append( elem ); + if ( theGroup ) + theGroup->Add( elem ); + + nPrev = n; + } + + // return a vector + + gp_XYZ pMid = 0.5 * ( path.myPoints[0] + path.myPoints.back() ); + if ( isVectorOK[ iSeg ]) + { + // find the most distance point of a path + double maxDist = 0; + for ( size_t iP = 1; iP < path.myPoints.size(); ++iP ) + { + double dist = Abs( theSegments[iSeg].myVector * ( path.myPoints[iP] - path.myPoints[0] )); + if ( dist > maxDist ) + { + maxDist = dist; + theSegments[iSeg].myMidProjPoint = path.myPoints[iP]; + } + } + if ( maxDist < Precision::Confusion() ) // planar case + theSegments[iSeg].myMidProjPoint = + pMid + theSegments[iSeg].myVector.XYZ().Normalized() * path.myLength * planarCoef; + } + theSegments[iSeg].myVector = gp_Vec( pMid, theSegments[iSeg].myMidProjPoint ); + } + + return; +} diff --git a/src/SMESH/SMESH_MeshEditor.hxx b/src/SMESH/SMESH_MeshEditor.hxx index 663b6ae16..1773a1bf6 100644 --- a/src/SMESH/SMESH_MeshEditor.hxx +++ b/src/SMESH/SMESH_MeshEditor.hxx @@ -46,8 +46,10 @@ class SMDS_MeshElement; class SMDS_MeshFace; class SMDS_MeshNode; +class SMESHDS_Group; class SMESHDS_Mesh; class SMESHDS_SubMesh; +class SMESH_ElementSearcher; class SMESH_Group; class SMESH_Mesh; class SMESH_MesherHelper; @@ -173,7 +175,7 @@ public: * \param theElems - The triangles to be fused. * \param theCriterion - Is used to choose a neighbour to fuse with. * \param theMaxAngle - Is a max angle between element normals at which fusion - * is still performed; theMaxAngle is mesured in radians. + * is still performed; theMaxAngle is measured in radians. * \return bool - Success or not. */ bool TriToQuad (TIDSortedElemSet & theElems, @@ -181,7 +183,7 @@ public: const double theMaxAngle); /*! * \brief Split quadrangles into triangles. - * \param theElems - The faces to be splitted. + * \param theElems - The faces to be split. * \param theCriterion - Is used to choose a diagonal for splitting. * \return bool - Success or not. */ @@ -189,7 +191,7 @@ public: SMESH::Controls::NumericalFunctorPtr theCriterion); /*! * \brief Split quadrangles into triangles. - * \param theElems - The faces to be splitted. + * \param theElems - The faces to be split. * \param the13Diag - Is used to choose a diagonal for splitting. * \return bool - Success or not. */ @@ -707,6 +709,42 @@ public: bool toAddExistingBondary = false, bool aroundElements = false); + + // structure used in MakePolyLine() to define a cutting plane + struct PolySegment + { + // 2 points: if myNode2 != 0, then the point is the middle of a face edge defined + // by two nodes, else it is at myNode1 + const SMDS_MeshNode* myNode1[2]; + const SMDS_MeshNode* myNode2[2]; + + gp_Vec myVector; // vector on the plane; to use a default plane set vector = (0,0,0) + + // point to return coordinates of a middle of the two points, projected to mesh + gp_Pnt myMidProjPoint; + }; + typedef std::vector TListOfPolySegments; + + /*! + * \brief Create a polyline consisting of 1D mesh elements each lying on a 2D element of + * the initial mesh. Positions of new nodes are found by cutting the mesh by the + * plane passing through pairs of points specified by each PolySegment structure. + * If there are several paths connecting a pair of points, the shortest path is + * selected by the module. Position of the cutting plane is defined by the two + * points and an optional vector lying on the plane specified by a PolySegment. + * By default the vector is defined by Mesh module as following. A middle point + * of the two given points is computed. The middle point is projected to the mesh. + * The vector goes from the middle point to the projection point. In case of planar + * mesh, the vector is normal to the mesh. + * \param [inout] segments - PolySegment's defining positions of cutting planes. + * Return the used vector and position of the middle point. + * \param [in] group - an optional group where created mesh segments will + * be added. + */ + void MakePolyLine( TListOfPolySegments& segments, + SMESHDS_Group* group=0, + SMESH_ElementSearcher* searcher=0); + private: /*! diff --git a/src/SMESH/SMESH_MesherHelper.cxx b/src/SMESH/SMESH_MesherHelper.cxx index 4d8f9952a..6b167f132 100644 --- a/src/SMESH/SMESH_MesherHelper.cxx +++ b/src/SMESH/SMESH_MesherHelper.cxx @@ -2179,13 +2179,30 @@ SMDS_MeshVolume* SMESH_MesherHelper::AddVolume(const SMDS_MeshNode* n1, const SMDS_MeshNode* n14 = GetMediumNode( n1, n4, force3d, TopAbs_SOLID ); const SMDS_MeshNode* n25 = GetMediumNode( n2, n5, force3d, TopAbs_SOLID ); const SMDS_MeshNode* n36 = GetMediumNode( n3, n6, force3d, TopAbs_SOLID ); + if ( myCreateBiQuadratic ) + { + const SMDS_MeshNode* n1245 = GetCentralNode( n1,n2,n4,n5,n12,n25,n45,n14,force3d ); + const SMDS_MeshNode* n1346 = GetCentralNode( n1,n3,n4,n6,n31,n36,n64,n14,force3d ); + const SMDS_MeshNode* n2356 = GetCentralNode( n2,n3,n6,n5,n23,n36,n56,n25,force3d ); - if(id) - elem = meshDS->AddVolumeWithID(n1, n2, n3, n4, n5, n6, - n12, n23, n31, n45, n56, n64, n14, n25, n36, id); + if(id) + elem = meshDS->AddVolumeWithID(n1, n2, n3, n4, n5, n6, + n12, n23, n31, n45, n56, n64, n14, n25, n36, + n1245, n2356, n1346, id); + else + elem = meshDS->AddVolume(n1, n2, n3, n4, n5, n6, + n12, n23, n31, n45, n56, n64, n14, n25, n36, + n1245, n2356, n1346); + } else - elem = meshDS->AddVolume(n1, n2, n3, n4, n5, n6, - n12, n23, n31, n45, n56, n64, n14, n25, n36); + { + if(id) + elem = meshDS->AddVolumeWithID(n1, n2, n3, n4, n5, n6, + n12, n23, n31, n45, n56, n64, n14, n25, n36, id); + else + elem = meshDS->AddVolume(n1, n2, n3, n4, n5, n6, + n12, n23, n31, n45, n56, n64, n14, n25, n36); + } } if ( mySetElemOnShape && myShapeID > 0 ) meshDS->SetMeshElementOnShape( elem, myShapeID ); @@ -3443,6 +3460,24 @@ double SMESH_MesherHelper::GetOtherParam(const double param) const return fabs(param-myPar1[i]) < fabs(param-myPar2[i]) ? myPar2[i] : myPar1[i]; } +//======================================================================= +//function : NbRealSeam +//purpose : Return a number of real seam edges in the shape set through +// IsQuadraticSubMesh() or SetSubShape(). A real seam edge encounters twice in a wire +//======================================================================= + +size_t SMESH_MesherHelper::NbRealSeam() const +{ + size_t nb = 0; + + std::set< int >::const_iterator id = mySeamShapeIds.begin(); + for ( ; id != mySeamShapeIds.end(); ++id ) + if ( *id < 0 ) ++nb; + else break; + + return nb; +} + //======================================================================= //function : IsOnSeam //purpose : Check if UV is on seam. Return 0 if not, 1 for U seam, 2 for V seam @@ -4866,6 +4901,7 @@ namespace { // Structures used by FixQuadraticElements() void SMESH_MesherHelper::FixQuadraticElements(SMESH_ComputeErrorPtr& compError, bool volumeOnly) { + //MESSAGE("FixQuadraticElements " << volumeOnly); // setenv NO_FixQuadraticElements to know if FixQuadraticElements() is guilty of bad conversion if ( getenv("NO_FixQuadraticElements") ) return; @@ -4907,6 +4943,7 @@ void SMESH_MesherHelper::FixQuadraticElements(SMESH_ComputeErrorPtr& compError, nbfaces = faces.Extent(); /*avoid "unused varianbles": */ nbfaces++, nbfaces--; #endif for ( TopTools_MapIteratorOfMapOfShape fIt( faces ); fIt.More(); fIt.Next() ) { + MESSAGE("FIX FACE " << nbfaces-- << " #" << GetMeshDS()->ShapeToIndex(fIt.Key())); MSG("FIX FACE " << nbfaces-- << " #" << GetMeshDS()->ShapeToIndex(fIt.Key())); SMESH_MesherHelper h(*myMesh); h.SetSubShape( fIt.Key() ); @@ -5107,7 +5144,7 @@ void SMESH_MesherHelper::FixQuadraticElements(SMESH_ComputeErrorPtr& compError, MSG("Internal chain - ignore"); continue; } - // mesure chain length and compute link position along the chain + // measure chain length and compute link position along the chain double chainLen = 0; vector< double > linkPos; TChain savedChain; // backup @@ -5263,10 +5300,11 @@ void SMESH_MesherHelper::FixQuadraticElements(SMESH_ComputeErrorPtr& compError, // 4. Move nodes // ------------- - TIDSortedElemSet biQuadQuas, biQuadTris, triQuadHexa; + TIDSortedElemSet biQuadQuas, biQuadTris, triQuadHexa, biQuadPenta; const bool toFixCentralNodes = ( myMesh->NbBiQuadQuadrangles() + myMesh->NbBiQuadTriangles() + - myMesh->NbTriQuadraticHexas() ); + myMesh->NbTriQuadraticHexas() + + myMesh->NbBiQuadPrisms()); double distXYZ[4]; faceHlp.ToFixNodeParameters( true ); @@ -5302,6 +5340,7 @@ void SMESH_MesherHelper::FixQuadraticElements(SMESH_ComputeErrorPtr& compError, case SMDSEntity_BiQuad_Quadrangle: biQuadQuas.insert( e ); break; case SMDSEntity_BiQuad_Triangle: biQuadTris.insert( e ); break; case SMDSEntity_TriQuad_Hexa: triQuadHexa.insert( e ); break; + case SMDSEntity_BiQuad_Penta: biQuadPenta.insert( e ); break; default:; } } @@ -5452,6 +5491,16 @@ void SMESH_MesherHelper::FixQuadraticElements(SMESH_ComputeErrorPtr& compError, nCenterCoords.X(), nCenterCoords.Y(), nCenterCoords.Z()); } } + // treat tri-quadratic hexahedra + { + SMDS_VolumeTool volExp; + TIDSortedElemSet::iterator pentIt = biQuadPenta.begin(); + for ( ; pentIt != biQuadPenta.end(); ++pentIt ) + { + MESSAGE("---"); + volExp.Set( *pentIt, /*ignoreCentralNodes=*/false ); + } + } #ifdef _DEBUG_ // avoid warning: defined but not used operator<<() SMESH_Comment() << *links.begin() << *faces.begin(); diff --git a/src/SMESH/SMESH_MesherHelper.hxx b/src/SMESH/SMESH_MesherHelper.hxx index cf3506fea..d4f54833a 100644 --- a/src/SMESH/SMESH_MesherHelper.hxx +++ b/src/SMESH/SMESH_MesherHelper.hxx @@ -52,7 +52,7 @@ typedef std::map::iterator ItTLinkNode; typedef SMDS_Iterator PShapeIterator; typedef boost::shared_ptr< PShapeIterator > PShapeIteratorPtr; - + typedef std::vector TNodeColumn; typedef std::map< double, TNodeColumn > TParam2ColumnMap; @@ -561,9 +561,15 @@ public: /*! * \brief Check if the shape set through IsQuadraticSubMesh() or SetSubShape() * has a degenerated edges - * \retval bool - true if it has + * \retval bool - true if there are degenerated edges */ bool HasDegeneratedEdges() const { return !myDegenShapeIds.empty(); } + /*! + * \brief Return a number of degenerated edges in the shape set through + * IsQuadraticSubMesh() or SetSubShape() + * \retval size_t - nb edges + */ + size_t NbDegeneratedEdges() const { return myDegenShapeIds.size(); } /*! * \brief Check if shape is a seam edge or it's vertex @@ -610,6 +616,12 @@ public: * \retval bool - true if it has */ bool HasRealSeam() const { return HasSeam() && ( *mySeamShapeIds.begin() < 0 ); } + /*! + * \brief Return a number of real seam edges in the shape set through + * IsQuadraticSubMesh() or SetSubShape(). A real seam edge encounters twice in a wire + * \retval size_t - nb of real seams + */ + size_t NbRealSeam() const; /*! * \brief Return index of periodic parametric direction of a closed face * \retval int - 1 for U, 2 for V direction diff --git a/src/SMESH/SMESH_Pattern.cxx b/src/SMESH/SMESH_Pattern.cxx index db6e60e8c..51564bf78 100644 --- a/src/SMESH/SMESH_Pattern.cxx +++ b/src/SMESH/SMESH_Pattern.cxx @@ -75,8 +75,6 @@ #include #include -#include - #include #include "utilities.h" diff --git a/src/SMESH/SMESH_ProxyMesh.cxx b/src/SMESH/SMESH_ProxyMesh.cxx index f994b83ec..a28033fda 100644 --- a/src/SMESH/SMESH_ProxyMesh.cxx +++ b/src/SMESH/SMESH_ProxyMesh.cxx @@ -95,7 +95,7 @@ SMESH_ProxyMesh::SMESH_ProxyMesh(std::vector& components): //================================================================================ /*! - * \brief Destructor deletes proxy submeshes and tmp elemens + * \brief Destructor deletes proxy submeshes and tmp elements */ //================================================================================ diff --git a/src/SMESH/SMESH_subMesh.cxx b/src/SMESH/SMESH_subMesh.cxx index 22fa65b99..2f89997ba 100644 --- a/src/SMESH/SMESH_subMesh.cxx +++ b/src/SMESH/SMESH_subMesh.cxx @@ -38,8 +38,6 @@ #include "SMESH_MesherHelper.hxx" #include "SMESH_subMeshEventListener.hxx" -#include - #include "utilities.h" #include "OpUtil.hxx" #include "Basics_Utils.hxx" diff --git a/src/SMESHDS/SMESHDS_Command.cxx b/src/SMESHDS/SMESHDS_Command.cxx index 05aece9a6..3c2ae95d4 100644 --- a/src/SMESHDS/SMESHDS_Command.cxx +++ b/src/SMESHDS/SMESHDS_Command.cxx @@ -684,6 +684,43 @@ void SMESHDS_Command::AddVolume(int NewVolID, int n1, int n2, myIntegers.push_back(n36); myNumber++; } +//======================================================================= +//function : AddVolume +//purpose : +//======================================================================= +void SMESHDS_Command::AddVolume(int NewVolID, int n1, int n2, + int n3, int n4, int n5,int n6, + int n12, int n23, int n31, + int n45, int n56, int n64, + int n14, int n25, int n36, + int n1245, int n2356, int n1346) +{ + if ( myType != SMESHDS_AddBiQuadPentahedron) { + MESSAGE("SMESHDS_Command::AddVolume : Bad Type"); + return; + } + myIntegers.push_back(NewVolID); + myIntegers.push_back(n1); + myIntegers.push_back(n2); + myIntegers.push_back(n3); + myIntegers.push_back(n4); + myIntegers.push_back(n5); + myIntegers.push_back(n6); + myIntegers.push_back(n12); + myIntegers.push_back(n23); + myIntegers.push_back(n31); + myIntegers.push_back(n45); + myIntegers.push_back(n56); + myIntegers.push_back(n64); + myIntegers.push_back(n14); + myIntegers.push_back(n25); + myIntegers.push_back(n36); + myIntegers.push_back(n1245); + myIntegers.push_back(n2356); + myIntegers.push_back(n1346); + myNumber++; +} + //======================================================================= //function : AddVolume @@ -735,7 +772,7 @@ void SMESHDS_Command::AddVolume(int NewVolID, int n1, int n2, int n3, int n1234,int n1256,int n2367,int n3478, int n1458,int n5678,int nCenter) { - if ( myType != SMESHDS_AddQuadHexahedron) { + if ( myType != SMESHDS_AddTriQuadHexa) { MESSAGE("SMESHDS_Command::AddVolume : Bad Type"); return; } diff --git a/src/SMESHDS/SMESHDS_Command.hxx b/src/SMESHDS/SMESHDS_Command.hxx index 799de67e2..4af0053dd 100644 --- a/src/SMESHDS/SMESHDS_Command.hxx +++ b/src/SMESHDS/SMESHDS_Command.hxx @@ -83,6 +83,12 @@ class SMESHDS_EXPORT SMESHDS_Command int n12, int n23, int n31, int n45, int n56, int n64, int n14, int n25, int n36); + void AddVolume(int NewVolID, int n1, int n2, int n3, + int n4, int n5, int n6, + int n12, int n23, int n31, + int n45, int n56, int n64, + int n14, int n25, int n36, + int n1245, int n2356, int n1346); void AddVolume(int NewVolID, int n1, int n2, int n3, int n4, int n5, int n6, int n7, int n8, int n12, int n23, int n34, int n41, diff --git a/src/SMESHDS/SMESHDS_CommandType.hxx b/src/SMESHDS/SMESHDS_CommandType.hxx index 1d03cc2c0..f1a21adce 100644 --- a/src/SMESHDS/SMESHDS_CommandType.hxx +++ b/src/SMESHDS/SMESHDS_CommandType.hxx @@ -58,6 +58,7 @@ enum SMESHDS_CommandType { SMESHDS_Add0DElement, SMESHDS_AddBiQuadTriangle, SMESHDS_AddBiQuadQuadrangle, + SMESHDS_AddBiQuadPentahedron, SMESHDS_AddTriQuadHexa, SMESHDS_AddHexagonalPrism, SMESHDS_AddBall diff --git a/src/SMESHDS/SMESHDS_Mesh.cxx b/src/SMESHDS/SMESHDS_Mesh.cxx index e7a10d7fe..865e700c1 100644 --- a/src/SMESHDS/SMESHDS_Mesh.cxx +++ b/src/SMESHDS/SMESHDS_Mesh.cxx @@ -1862,7 +1862,7 @@ SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1, //======================================================================= //function : AddVolume -//purpose : +//purpose : 2nd order pentahedron (prism) with 15 nodes //======================================================================= SMDS_MeshVolume* SMESHDS_Mesh::AddVolume(const SMDS_MeshNode * n1, const SMDS_MeshNode * n2, @@ -1893,7 +1893,7 @@ SMDS_MeshVolume* SMESHDS_Mesh::AddVolume(const SMDS_MeshNode * n1, //======================================================================= //function : AddVolumeWithID -//purpose : +//purpose : 2nd order pentahedron (prism) with 15 nodes //======================================================================= SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4, int n5, int n6, @@ -1909,10 +1909,96 @@ SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, n45,n56,n64,n14,n25,n36); return anElem; } + +//======================================================================= +//function : AddVolumeWithID +//purpose : 2d order Pentahedron (prism) with 15 nodes +//======================================================================= +SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1, + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3, + const SMDS_MeshNode * n4, + const SMDS_MeshNode * n5, + const SMDS_MeshNode * n6, + const SMDS_MeshNode * n12, + const SMDS_MeshNode * n23, + const SMDS_MeshNode * n31, + const SMDS_MeshNode * n45, + const SMDS_MeshNode * n56, + const SMDS_MeshNode * n64, + const SMDS_MeshNode * n14, + const SMDS_MeshNode * n25, + const SMDS_MeshNode * n36, + int ID) +{ + return AddVolumeWithID(n1->GetID(), n2->GetID(), n3->GetID(), + n4->GetID(), n5->GetID(), n6->GetID(), + n12->GetID(), n23->GetID(), n31->GetID(), + n45->GetID(), n56->GetID(), n64->GetID(), + n14->GetID(), n25->GetID(), n36->GetID(), + ID); +} +//======================================================================= +//function : AddVolume +//purpose : 2nd order pentahedron (prism) with 18 nodes +//======================================================================= +SMDS_MeshVolume* SMESHDS_Mesh::AddVolume(const SMDS_MeshNode * n1, + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3, + const SMDS_MeshNode * n4, + const SMDS_MeshNode * n5, + const SMDS_MeshNode * n6, + const SMDS_MeshNode * n12, + const SMDS_MeshNode * n23, + const SMDS_MeshNode * n31, + const SMDS_MeshNode * n45, + const SMDS_MeshNode * n56, + const SMDS_MeshNode * n64, + const SMDS_MeshNode * n14, + const SMDS_MeshNode * n25, + const SMDS_MeshNode * n36, + const SMDS_MeshNode * n1245, + const SMDS_MeshNode * n2356, + const SMDS_MeshNode * n1346) +{ + SMDS_MeshVolume *anElem = SMDS_Mesh::AddVolume(n1,n2,n3,n4,n5,n6,n12,n23,n31, + n45,n56,n64,n14,n25,n36, + n1245, n2356, n1346); + if(anElem) + myScript->AddVolume(anElem->GetID(), n1->GetID(), n2->GetID(), + n3->GetID(), n4->GetID(), n5->GetID(), n6->GetID(), + n12->GetID(), n23->GetID(), n31->GetID(), + n45->GetID(), n56->GetID(), n64->GetID(), + n14->GetID(), n25->GetID(), n36->GetID(), + n1245->GetID(), n2356->GetID(), n1346->GetID()); + return anElem; +} + +//======================================================================= +//function : AddVolumeWithID +//purpose : 2nd order pentahedron (prism) with 18 nodes +//======================================================================= +SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, + int n4, int n5, int n6, + int n12,int n23,int n31, + int n45,int n56,int n64, + int n14,int n25,int n36, + int n1245, int n2356, int n1346, + int ID) +{ + SMDS_MeshVolume *anElem = SMDS_Mesh::AddVolumeWithID(n1,n2,n3,n4,n5,n6, + n12,n23,n31, + n45,n56,n64, + n14,n25,n36, + n1245, n2356, n1346, ID); + if(anElem) myScript->AddVolume(ID,n1,n2,n3,n4,n5,n6,n12,n23,n31, + n45,n56,n64,n14,n25,n36, n1245, n2356, n1346); + return anElem; +} //======================================================================= //function : AddVolumeWithID -//purpose : 2d order Pentahedron with 15 nodes +//purpose : 2d order Pentahedron with 18 nodes //======================================================================= SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1, const SMDS_MeshNode * n2, @@ -1929,6 +2015,9 @@ SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1, const SMDS_MeshNode * n14, const SMDS_MeshNode * n25, const SMDS_MeshNode * n36, + const SMDS_MeshNode * n1245, + const SMDS_MeshNode * n2356, + const SMDS_MeshNode * n1346, int ID) { return AddVolumeWithID(n1->GetID(), n2->GetID(), n3->GetID(), @@ -1936,7 +2025,7 @@ SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1, n12->GetID(), n23->GetID(), n31->GetID(), n45->GetID(), n56->GetID(), n64->GetID(), n14->GetID(), n25->GetID(), n36->GetID(), - ID); + n1245->GetID(), n2356->GetID(), n1346->GetID(), ID); } diff --git a/src/SMESHDS/SMESHDS_Mesh.hxx b/src/SMESHDS/SMESHDS_Mesh.hxx index 89d69e3c5..92f631890 100644 --- a/src/SMESHDS/SMESHDS_Mesh.hxx +++ b/src/SMESHDS/SMESHDS_Mesh.hxx @@ -389,6 +389,52 @@ public: const SMDS_MeshNode * n25, const SMDS_MeshNode * n36); + // 2d order Pentahedron with 18 nodes + virtual SMDS_MeshVolume* AddVolumeWithID(int n1, int n2, int n3, + int n4, int n5, int n6, + int n12,int n23,int n31, + int n45,int n56,int n64, + int n14,int n25,int n36, + int n1245, int n2356, int n1346, + int ID); + virtual SMDS_MeshVolume* AddVolumeWithID(const SMDS_MeshNode * n1, + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3, + const SMDS_MeshNode * n4, + const SMDS_MeshNode * n5, + const SMDS_MeshNode * n6, + const SMDS_MeshNode * n12, + const SMDS_MeshNode * n23, + const SMDS_MeshNode * n31, + const SMDS_MeshNode * n45, + const SMDS_MeshNode * n56, + const SMDS_MeshNode * n64, + const SMDS_MeshNode * n14, + const SMDS_MeshNode * n25, + const SMDS_MeshNode * n36, + const SMDS_MeshNode * n1245, + const SMDS_MeshNode * n2356, + const SMDS_MeshNode * n1346, + int ID); + virtual SMDS_MeshVolume* AddVolume(const SMDS_MeshNode * n1, + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3, + const SMDS_MeshNode * n4, + const SMDS_MeshNode * n5, + const SMDS_MeshNode * n6, + const SMDS_MeshNode * n12, + const SMDS_MeshNode * n23, + const SMDS_MeshNode * n31, + const SMDS_MeshNode * n45, + const SMDS_MeshNode * n56, + const SMDS_MeshNode * n64, + const SMDS_MeshNode * n14, + const SMDS_MeshNode * n25, + const SMDS_MeshNode * n36, + const SMDS_MeshNode * n1245, + const SMDS_MeshNode * n2356, + const SMDS_MeshNode * n1346); + // 2d order Hexahedrons with 20 nodes virtual SMDS_MeshVolume* AddVolumeWithID(int n1, int n2, int n3, int n4, int n5, int n6, int n7, int n8, diff --git a/src/SMESHDS/SMESHDS_Script.cxx b/src/SMESHDS/SMESHDS_Script.cxx index f912b7682..de368f199 100644 --- a/src/SMESHDS/SMESHDS_Script.cxx +++ b/src/SMESHDS/SMESHDS_Script.cxx @@ -550,6 +550,27 @@ void SMESHDS_Script::AddVolume(int NewVolID, int n1, int n2, int n3, int n4, //function : AddVolume //purpose : //======================================================================= +void SMESHDS_Script::AddVolume(int NewVolID, int n1, int n2, int n3, int n4, + int n5,int n6, int n12, int n23, int n31, + int n45, int n56, int n64, + int n14, int n25, int n36, + int n1245, int n2356, int n1346) +{ + if(myIsEmbeddedMode){ + myIsModified = true; + return; + } + getCommand(SMESHDS_AddBiQuadPentahedron)->AddVolume(NewVolID, n1,n2,n3,n4,n5,n6, + n12, n23, n31, + n45, n56, n64, + n14, n25, n36, + n1245, n2356, n1346); +} + +//======================================================================= +//function : AddVolume +//purpose : +//======================================================================= void SMESHDS_Script::AddVolume(int NewVolID, int n1, int n2, int n3, int n4, int n5, int n6, int n7, int n8, int n12, int n23, int n34, int n41, diff --git a/src/SMESHDS/SMESHDS_Script.hxx b/src/SMESHDS/SMESHDS_Script.hxx index 87a081061..7b3c2fc9c 100644 --- a/src/SMESHDS/SMESHDS_Script.hxx +++ b/src/SMESHDS/SMESHDS_Script.hxx @@ -91,6 +91,12 @@ class SMESHDS_EXPORT SMESHDS_Script int n12, int n23, int n31, int n45, int n56, int n64, int n14, int n25, int n36); + void AddVolume(int NewVolID, int n1, int n2, int n3, + int n4, int n5, int n6, + int n12, int n23, int n31, + int n45, int n56, int n64, + int n14, int n25, int n36, + int n1245, int n2356, int n1346); void AddVolume(int NewVolID, int n1, int n2, int n3, int n4, int n5, int n6, int n7, int n8, int n12, int n23, int n34, int n41, diff --git a/src/SMESHGUI/SMESHGUI.cxx b/src/SMESHGUI/SMESHGUI.cxx index e3b49472b..2e698c6de 100644 --- a/src/SMESHGUI/SMESHGUI.cxx +++ b/src/SMESHGUI/SMESHGUI.cxx @@ -143,6 +143,7 @@ #include CORBA_CLIENT_HEADER(SALOMEDS_Attributes) #include CORBA_CLIENT_HEADER(SMESH_MeshEditor) #include CORBA_CLIENT_HEADER(SMESH_Measurements) +#include CORBA_CLIENT_HEADER(SMESH_Mesh) // Qt includes // #define INCLUDE_MENUITEM_DEF // VSR commented ???????? @@ -603,6 +604,7 @@ namespace notSupportedElemTypes.push_back( SMESH::Entity_Quad_Polygon ); notSupportedElemTypes.push_back( SMESH::Entity_Quad_Pyramid ); notSupportedElemTypes.push_back( SMESH::Entity_Quad_Penta ); + notSupportedElemTypes.push_back( SMESH::Entity_BiQuad_Penta ); notSupportedElemTypes.push_back( SMESH::Entity_Hexagonal_Prism ); notSupportedElemTypes.push_back( SMESH::Entity_Polyhedra ); notSupportedElemTypes.push_back( SMESH::Entity_Quad_Polyhedra ); @@ -626,6 +628,7 @@ namespace "SMESH_TETRAHEDRA","SMESH_QUADRATIC_TETRAHEDRONS","SMESH_PYRAMIDS", "SMESH_QUADRATIC_PYRAMIDS","SMESH_HEXAHEDRA","SMESH_QUADRATIC_HEXAHEDRONS", "SMESH_TRIQUADRATIC_HEXAHEDRONS","SMESH_PENTAHEDRA","SMESH_QUADRATIC_PENTAHEDRONS", + "SMESH_BIQUADRATIC_PENTAHEDRONS", "SMESH_OCTAHEDRA","SMESH_POLYEDRONS","SMESH_QUADRATIC_POLYEDRONS","SMESH_BALLS" }; // is typeMsg complete? (compilation failure mains that enum SMDSAbs_EntityType changed) @@ -683,7 +686,14 @@ namespace } else if ( isCGNS )// Export to CGNS { - SUIT_FileDlg* fd = new SUIT_FileDlg( SMESHGUI::desktop(), false, true, true ); + const char* theByTypeResource = "cgns_group_elems_by_type"; + toCreateGroups = SMESHGUI::resourceMgr()->booleanValue( "SMESH", theByTypeResource, false ); + + QStringList checkBoxes; + checkBoxes << QObject::tr("CGNS_EXPORT_ELEMS_BY_TYPE"); + + SalomeApp_CheckFileDlg* fd = + new SalomeApp_CheckFileDlg ( SMESHGUI::desktop(), false, checkBoxes, true, true ); fd->setWindowTitle( aTitle ); fd->setNameFilter( QObject::tr( "CGNS_FILES_FILTER" ) + " (*.cgns)" ); if ( !anInitialPath.isEmpty() ) @@ -691,10 +701,13 @@ namespace fd->selectFile(aMeshName); SMESHGUI_FileValidator* fv = new SMESHGUI_FileValidator( fd ); fd->setValidator( fv ); + fd->SetChecked( toCreateGroups, 0 ); if ( fd->exec() ) aFilename = fd->selectedFile(); - toOverwrite = fv->isOverwrite(); + toOverwrite = fv->isOverwrite(); + toCreateGroups = fd->IsChecked(0); + SMESHGUI::resourceMgr()->setValue("SMESH", theByTypeResource, toCreateGroups ); delete fd; } @@ -740,7 +753,7 @@ namespace SMESHGUI_FieldSelectorWdg* fieldSelWdg = new SMESHGUI_FieldSelectorWdg(); QList< QWidget* > wdgList; - if ( fieldSelWdg->GetAllFeilds( aMeshList, aFieldList )) + if ( fieldSelWdg->GetAllFields( aMeshList, aFieldList )) wdgList.append( fieldSelWdg ); SalomeApp_CheckFileDlg* fd = @@ -822,7 +835,7 @@ namespace } toCreateGroups = fd->IsChecked(0); toFindOutDim = fd->IsChecked(1); - fieldSelWdg->GetSelectedFeilds(); + fieldSelWdg->GetSelectedFields(); if ( !fieldSelWdg->parent() ) delete fieldSelWdg; delete fd; @@ -912,7 +925,8 @@ namespace SMESH::SMESH_Mesh_var aMeshItem = aMeshOrGroup->GetMesh(); aMeshItem->ExportCGNS( aMeshOrGroup, aFilename.toUtf8().data(), - toOverwrite && aMeshIndex == 0 ); + toOverwrite && aMeshIndex == 0, + toCreateGroups ); } } else if ( isGMF ) @@ -1089,6 +1103,8 @@ namespace type = QObject::tr( "LENGTH_EDGES" ); else if ( dynamic_cast< SMESH::Controls::Length2D* >( f.get() ) ) type = QObject::tr( "LENGTH2D_EDGES" ); + else if ( dynamic_cast< SMESH::Controls::Deflection2D* >( f.get() ) ) + type = QObject::tr( "DEFLECTION2D_FACES" ); else if ( dynamic_cast< SMESH::Controls::MultiConnection* >( f.get() ) ) type = QObject::tr( "MULTI_BORDERS" ); else if ( dynamic_cast< SMESH::Controls::MultiConnection2D* >( f.get() ) ) @@ -1621,6 +1637,7 @@ namespace ActionControl.Bind( SMESHOp::OpBareBorderFace, SMESH_Actor::eBareBorderFace ); ActionControl.Bind( SMESHOp::OpOverConstrainedFace, SMESH_Actor::eOverConstrainedFace ); ActionControl.Bind( SMESHOp::OpLength2D, SMESH_Actor::eLength2D ); + ActionControl.Bind( SMESHOp::OpDeflection2D, SMESH_Actor::eDeflection2D ); ActionControl.Bind( SMESHOp::OpConnection2D, SMESH_Actor::eMultiConnection2D ); ActionControl.Bind( SMESHOp::OpArea, SMESH_Actor::eArea ); ActionControl.Bind( SMESHOp::OpTaper, SMESH_Actor::eTaper ); @@ -2074,7 +2091,7 @@ bool SMESHGUI::automaticUpdate( SMESH::SMESH_IDSource_ptr theMesh, long nbVolumes = info[SMDSEntity_Tetra] + info[SMDSEntity_Quad_Tetra] + info[SMDSEntity_Hexa] + info[SMDSEntity_Quad_Hexa] + info[SMDSEntity_TriQuad_Hexa] + info[SMDSEntity_Pyramid] + info[SMDSEntity_Quad_Pyramid] + - info[SMDSEntity_Penta] + info[SMDSEntity_Quad_Penta] + + info[SMDSEntity_Penta] + info[SMDSEntity_Quad_Penta] + info[SMDSEntity_BiQuad_Penta] + info[SMDSEntity_Polyhedra] + info[SMDSEntity_Hexagonal_Prism]; long nbBalls = info[SMDSEntity_Ball]; @@ -2569,9 +2586,7 @@ bool SMESHGUI::OnGUIEvent( int theCommandID ) if(isStudyLocked()) break; SUIT_OverrideCursor wc; try { -#if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100 OCC_CATCH_SIGNALS; -#endif SMESH::UpdateView(); } catch (std::bad_alloc) { // PAL16774 (Crash after display of many groups) @@ -3229,6 +3244,7 @@ bool SMESHGUI::OnGUIEvent( int theCommandID ) case SMESHOp::OpQuadraticTetrahedron: case SMESHOp::OpQuadraticPyramid: case SMESHOp::OpQuadraticPentahedron: + case SMESHOp::OpBiQuadraticPentahedron: case SMESHOp::OpQuadraticHexahedron: case SMESHOp::OpTriQuadraticHexahedron: { @@ -3247,6 +3263,7 @@ bool SMESHGUI::OnGUIEvent( int theCommandID ) case SMESHOp::OpQuadraticTetrahedron: type = SMDSEntity_Quad_Tetra; break; case SMESHOp::OpQuadraticPyramid: type = SMDSEntity_Quad_Pyramid; break; case SMESHOp::OpQuadraticPentahedron: type = SMDSEntity_Quad_Penta; break; + case SMESHOp::OpBiQuadraticPentahedron: type = SMDSEntity_BiQuad_Penta; break; case SMESHOp::OpQuadraticHexahedron: type = SMDSEntity_Quad_Hexa; break; case SMESHOp::OpTriQuadraticHexahedron: type = SMDSEntity_TriQuad_Hexa; break; default: break; @@ -3538,6 +3555,7 @@ bool SMESHGUI::OnGUIEvent( int theCommandID ) case SMESHOp::OpBareBorderFace: case SMESHOp::OpOverConstrainedFace: case SMESHOp::OpLength2D: + case SMESHOp::OpDeflection2D: case SMESHOp::OpConnection2D: case SMESHOp::OpArea: case SMESHOp::OpTaper: @@ -3839,6 +3857,7 @@ void SMESHGUI::initialize( CAM_Application* app ) createSMESHAction( SMESHOp::OpBareBorderFace, "BARE_BORDER_FACE", "ICON_BARE_BORDER_FACE", 0, true ); createSMESHAction( SMESHOp::OpOverConstrainedFace, "OVER_CONSTRAINED_FACE", "ICON_OVER_CONSTRAINED_FACE", 0, true ); createSMESHAction( SMESHOp::OpLength2D, "LENGTH_2D", "ICON_LENGTH_2D", 0, true ); + createSMESHAction( SMESHOp::OpDeflection2D, "DEFLECTION_2D", "ICON_DEFLECTION_2D", 0, true ); createSMESHAction( SMESHOp::OpConnection2D, "CONNECTION_2D", "ICON_CONNECTION_2D", 0, true ); createSMESHAction( SMESHOp::OpArea, "AREA", "ICON_AREA", 0, true ); createSMESHAction( SMESHOp::OpTaper, "TAPER", "ICON_TAPER", 0, true ); @@ -3879,6 +3898,7 @@ void SMESHGUI::initialize( CAM_Application* app ) createSMESHAction( SMESHOp::OpQuadraticTetrahedron, "QUADRATIC_TETRAHEDRON", "ICON_DLG_QUADRATIC_TETRAHEDRON" ); createSMESHAction( SMESHOp::OpQuadraticPyramid, "QUADRATIC_PYRAMID", "ICON_DLG_QUADRATIC_PYRAMID" ); createSMESHAction( SMESHOp::OpQuadraticPentahedron, "QUADRATIC_PENTAHEDRON", "ICON_DLG_QUADRATIC_PENTAHEDRON" ); + createSMESHAction( SMESHOp::OpBiQuadraticPentahedron, "BIQUADRATIC_PENTAHEDRON", "ICON_DLG_BIQUADRATIC_PENTAHEDRON" ); createSMESHAction( SMESHOp::OpQuadraticHexahedron, "QUADRATIC_HEXAHEDRON", "ICON_DLG_QUADRATIC_HEXAHEDRON" ); createSMESHAction( SMESHOp::OpTriQuadraticHexahedron, "TRIQUADRATIC_HEXAHEDRON", "ICON_DLG_TRIQUADRATIC_HEXAHEDRON" ); @@ -3967,6 +3987,7 @@ void SMESHGUI::initialize( CAM_Application* app ) << SMESHOp::OpNodeConnectivityNb // node controls << SMESHOp::OpFreeEdge << SMESHOp::OpFreeBorder << SMESHOp::OpLength << SMESHOp::OpConnection << SMESHOp::OpEqualEdge // edge controls + << SMESHOp::OpDeflection2D << SMESHOp::OpFreeFace << SMESHOp::OpLength2D << SMESHOp::OpConnection2D << SMESHOp::OpArea << SMESHOp::OpTaper << SMESHOp::OpAspectRatio << SMESHOp::OpMinimumAngle << SMESHOp::OpWarpingAngle << SMESHOp::OpSkew @@ -4080,6 +4101,7 @@ void SMESHGUI::initialize( CAM_Application* app ) createMenu( SMESHOp::OpSkew, faceId, -1 ); createMenu( SMESHOp::OpMaxElementLength2D, faceId, -1 ); createMenu( SMESHOp::OpEqualFace, faceId, -1 ); + createMenu( SMESHOp::OpDeflection2D, faceId, -1 ); createMenu( SMESHOp::OpAspectRatio3D, volumeId, -1 ); createMenu( SMESHOp::OpVolume, volumeId, -1 ); createMenu( SMESHOp::OpMaxElementLength3D, volumeId, -1 ); @@ -4115,6 +4137,7 @@ void SMESHGUI::initialize( CAM_Application* app ) createMenu( SMESHOp::OpQuadraticTetrahedron, addId, -1 ); createMenu( SMESHOp::OpQuadraticPyramid, addId, -1 ); createMenu( SMESHOp::OpQuadraticPentahedron, addId, -1 ); + createMenu( SMESHOp::OpBiQuadraticPentahedron, addId, -1 ); createMenu( SMESHOp::OpQuadraticHexahedron, addId, -1 ); createMenu( SMESHOp::OpTriQuadraticHexahedron, addId, -1 ); @@ -4228,6 +4251,7 @@ void SMESHGUI::initialize( CAM_Application* app ) createTool( SMESHOp::OpSkew, ctrl2dTb ); createTool( SMESHOp::OpMaxElementLength2D, ctrl2dTb ); createTool( SMESHOp::OpEqualFace, ctrl2dTb ); + createTool( SMESHOp::OpDeflection2D, ctrl2dTb ); createTool( SMESHOp::OpAspectRatio3D, ctrl3dTb ); createTool( SMESHOp::OpVolume, ctrl3dTb ); @@ -4260,6 +4284,7 @@ void SMESHGUI::initialize( CAM_Application* app ) createTool( SMESHOp::OpQuadraticTetrahedron, addNonElemTb ); createTool( SMESHOp::OpQuadraticPyramid, addNonElemTb ); createTool( SMESHOp::OpQuadraticPentahedron, addNonElemTb ); + createTool( SMESHOp::OpBiQuadraticPentahedron, addNonElemTb ); createTool( SMESHOp::OpQuadraticHexahedron, addNonElemTb ); createTool( SMESHOp::OpTriQuadraticHexahedron, addNonElemTb ); @@ -4638,10 +4663,15 @@ void SMESHGUI::initialize( CAM_Application* app ) popupMgr()->insert ( action( SMESHOp::OpOverConstrainedFace ), aSubId, -1 ); popupMgr()->setRule( action( SMESHOp::OpOverConstrainedFace ), aMeshInVtkHasFaces, QtxPopupMgr::VisibleRule ); popupMgr()->setRule( action( SMESHOp::OpOverConstrainedFace ), "controlMode = 'eOverConstrainedFace'", QtxPopupMgr::ToggleRule ); + popupMgr()->insert ( action( SMESHOp::OpEqualFace ), aSubId, -1 ); popupMgr()->setRule( action( SMESHOp::OpEqualFace ), aMeshInVtkHasFaces, QtxPopupMgr::VisibleRule ); popupMgr()->setRule( action( SMESHOp::OpEqualFace ), "controlMode = 'eCoincidentElems2D'", QtxPopupMgr::ToggleRule ); + popupMgr()->insert ( action( SMESHOp::OpDeflection2D ), aSubId, -1 ); + popupMgr()->setRule( action( SMESHOp::OpDeflection2D ), aMeshInVtkHasFaces + " && hasGeomReference", QtxPopupMgr::VisibleRule ); + popupMgr()->setRule( action( SMESHOp::OpDeflection2D ), "controlMode = 'eDeflection2D'", QtxPopupMgr::ToggleRule ); + aSubId = popupMgr()->insert( tr( "MEN_VOLUME_CTRL" ), anId, -1 ); // VOLUME CONTROLS popupMgr()->insert ( action( SMESHOp::OpAspectRatio3D ), aSubId, -1 ); diff --git a/src/SMESHGUI/SMESHGUI_AddQuadraticElementDlg.cxx b/src/SMESHGUI/SMESHGUI_AddQuadraticElementDlg.cxx index d23b06628..0c8b92b19 100644 --- a/src/SMESHGUI/SMESHGUI_AddQuadraticElementDlg.cxx +++ b/src/SMESHGUI/SMESHGUI_AddQuadraticElementDlg.cxx @@ -380,6 +380,9 @@ SMESHGUI_AddQuadraticElementDlg::SMESHGUI_AddQuadraticElementDlg( SMESHGUI* theM case SMDSEntity_Quad_Penta: anElementName = QString("QUADRATIC_PENTAHEDRON"); break; + case SMDSEntity_BiQuad_Penta: + anElementName = QString("BIQUADRATIC_PENTAHEDRON"); + break; case SMDSEntity_Quad_Hexa: anElementName = QString("QUADRATIC_HEXAHEDRON"); break; @@ -587,6 +590,12 @@ void SMESHGUI_AddQuadraticElementDlg::Init() myNbCorners = 6; myHelpFileName = "adding_quadratic_elements_page.html#?"; //Adding_pentahedrons break; + case SMDSEntity_BiQuad_Penta: + aNumRows = 9; + myNbCorners = 6; + myNbMidFaceNodes = 3; + myHelpFileName = "adding_quadratic_elements_page.html#?"; //Adding_pentahedrons + break; case SMDSEntity_Quad_Hexa: aNumRows = 12; myNbCorners = 8; @@ -707,6 +716,7 @@ bool SMESHGUI_AddQuadraticElementDlg::ClickOnApply() case SMDSEntity_Quad_Tetra: case SMDSEntity_Quad_Pyramid: case SMDSEntity_Quad_Penta: + case SMDSEntity_BiQuad_Penta: case SMDSEntity_Quad_Hexa: case SMDSEntity_TriQuad_Hexa: for ( int row = 0; row < myNbCorners; row++ ) @@ -790,6 +800,7 @@ bool SMESHGUI_AddQuadraticElementDlg::ClickOnApply() case SMDSEntity_Quad_Tetra: case SMDSEntity_Quad_Pyramid: case SMDSEntity_Quad_Penta: + case SMDSEntity_BiQuad_Penta: case SMDSEntity_Quad_Hexa: case SMDSEntity_TriQuad_Hexa: anElementType = SMESH::VOLUME; @@ -1068,6 +1079,7 @@ void SMESHGUI_AddQuadraticElementDlg::SelectionIntoArgument() case SMDSEntity_Quad_Tetra: case SMDSEntity_Quad_Pyramid: case SMDSEntity_Quad_Penta: + case SMDSEntity_BiQuad_Penta: case SMDSEntity_Quad_Hexa: case SMDSEntity_TriQuad_Hexa: anElementType = SMESH::VOLUME; break; @@ -1402,6 +1414,7 @@ void SMESHGUI_AddQuadraticElementDlg::UpdateTable( bool theConersValidity ) aLastColIds = LastPyramidIds; break; case SMDSEntity_Quad_Penta: + case SMDSEntity_BiQuad_Penta: aFirstColIds = FirstPentahedronIds; aLastColIds = LastPentahedronIds; break; diff --git a/src/SMESHGUI/SMESHGUI_ComputeDlg.cxx b/src/SMESHGUI/SMESHGUI_ComputeDlg.cxx index fa746f19a..3c3363d6f 100644 --- a/src/SMESHGUI/SMESHGUI_ComputeDlg.cxx +++ b/src/SMESHGUI/SMESHGUI_ComputeDlg.cxx @@ -1229,7 +1229,7 @@ void SMESHGUI_BaseComputeOp::showComputeResult( const bool theMemoryLack, currentCellChanged(); // to update buttons } } - // show dialog and wait, becase Compute can be invoked from Preview operation + // show dialog and wait, because Compute can be invoked from Preview operation //aCompDlg->exec(); // this way it becomes modal - impossible to rotate model in the Viewer aCompDlg->show(); } @@ -1535,7 +1535,7 @@ SMESHGUI_ComputeOp::SMESHGUI_ComputeOp() //================================================================================ /*! - * \brief Desctructor + * \brief Destructor */ //================================================================================ @@ -1978,9 +1978,7 @@ void SMESHGUI_PrecomputeOp::onPreview() SMESH::long_array_var aShapesId = new SMESH::long_array(); try { -#if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100 OCC_CATCH_SIGNALS; -#endif SMESH::MeshPreviewStruct_var previewData = gen->Precompute(myMesh, myMainShape, (SMESH::Dimension)dim, aShapesId); @@ -2003,9 +2001,7 @@ void SMESHGUI_PrecomputeOp::onPreview() } try { -#if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100 OCC_CATCH_SIGNALS; -#endif aCompErrors = gen->GetComputeErrors( myMesh, myMainShape ); // check if there are memory problems for ( CORBA::ULong i = 0; (i < aCompErrors->length()) && !memoryLack; ++i ) @@ -2152,7 +2148,7 @@ SMESHGUI_EvaluateOp::SMESHGUI_EvaluateOp() //================================================================================ /*! - * \brief Desctructor + * \brief Destructor */ //================================================================================ @@ -2221,9 +2217,7 @@ void SMESHGUI_BaseComputeOp::evaluateMesh() } SUIT_OverrideCursor aWaitCursor; try { -#if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100 OCC_CATCH_SIGNALS; -#endif aRes = gen->Evaluate(myMesh, myMainShape); } catch(const SALOME::SALOME_Exception & S_ex){ @@ -2231,9 +2225,7 @@ void SMESHGUI_BaseComputeOp::evaluateMesh() } try { -#if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100 OCC_CATCH_SIGNALS; -#endif aCompErrors = gen->GetComputeErrors( myMesh, myMainShape ); } catch(const SALOME::SALOME_Exception & S_ex){ @@ -2391,7 +2383,7 @@ void SMESHGUI_BaseComputeOp::showEvaluateResult(const SMESH::long_array& theRes, currentCellChanged(); // to update buttons } } - // show dialog and wait, becase Compute can be invoked from Preview operation + // show dialog and wait, because Compute can be invoked from Preview operation //aCompDlg->exec(); // this way it becomes modal - impossible to rotate model in the Viewer aCompDlg->show(); } diff --git a/src/SMESHGUI/SMESHGUI_ConvToQuadOp.cxx b/src/SMESHGUI/SMESHGUI_ConvToQuadOp.cxx index b412f118d..2e25f2c52 100644 --- a/src/SMESHGUI/SMESHGUI_ConvToQuadOp.cxx +++ b/src/SMESHGUI/SMESHGUI_ConvToQuadOp.cxx @@ -332,6 +332,7 @@ SMESHGUI_ConvToQuadOp::DestinationMesh( const SMESH::SMESH_IDSource_var& idSourc bool hasBiQuad = ( nbElemOfType[SMDSEntity_BiQuad_Triangle ] || nbElemOfType[SMDSEntity_BiQuad_Quadrangle ] || + nbElemOfType[SMDSEntity_BiQuad_Penta ] || nbElemOfType[SMDSEntity_TriQuad_Hexa ] ); bool hasLinBiQuad = ( nbElemOfType[SMDSEntity_Triangle ] || nbElemOfType[SMDSEntity_Quadrangle ] || diff --git a/src/SMESHGUI/SMESHGUI_FieldSelectorWdg.cxx b/src/SMESHGUI/SMESHGUI_FieldSelectorWdg.cxx index 7ab25ef53..816fe312b 100644 --- a/src/SMESHGUI/SMESHGUI_FieldSelectorWdg.cxx +++ b/src/SMESHGUI/SMESHGUI_FieldSelectorWdg.cxx @@ -86,7 +86,7 @@ SMESHGUI_FieldSelectorWdg::SMESHGUI_FieldSelectorWdg( QWidget* p ) * \brief Retrieves all fields defined on geometry of given meshes */ bool SMESHGUI_FieldSelectorWdg:: -GetAllFeilds(const QList< QPair< SMESH::SMESH_IDSource_var, QString > >& meshes, +GetAllFields(const QList< QPair< SMESH::SMESH_IDSource_var, QString > >& meshes, QList< QPair< GEOM::ListOfFields_var, QString > >& fields) { myFields = & fields; @@ -165,7 +165,7 @@ GetAllFeilds(const QList< QPair< SMESH::SMESH_IDSource_var, QString > >& meshes, /*! * \brief Filter off not selected fields from myFields */ -bool SMESHGUI_FieldSelectorWdg::GetSelectedFeilds() +bool SMESHGUI_FieldSelectorWdg::GetSelectedFields() { int nbSelected = 0; if ( myTree->isEnabled() ) diff --git a/src/SMESHGUI/SMESHGUI_FieldSelectorWdg.h b/src/SMESHGUI/SMESHGUI_FieldSelectorWdg.h index 8a88bf41d..025a4de73 100644 --- a/src/SMESHGUI/SMESHGUI_FieldSelectorWdg.h +++ b/src/SMESHGUI/SMESHGUI_FieldSelectorWdg.h @@ -43,13 +43,13 @@ class SMESHGUI_EXPORT SMESHGUI_FieldSelectorWdg : public QGroupBox public: SMESHGUI_FieldSelectorWdg( QWidget* = 0 ); - bool GetAllFeilds(const QList< QPair< SMESH::SMESH_IDSource_var, QString > >& meshes, + bool GetAllFields(const QList< QPair< SMESH::SMESH_IDSource_var, QString > >& meshes, QList< QPair< GEOM::ListOfFields_var, QString > >& fields); - bool GetSelectedFeilds(); + bool GetSelectedFields(); private slots: - + void onItemCheck(QTreeWidgetItem * item, int column); private: diff --git a/src/SMESHGUI/SMESHGUI_Filter.cxx b/src/SMESHGUI/SMESHGUI_Filter.cxx index 05d003387..1222c4b80 100755 --- a/src/SMESHGUI/SMESHGUI_Filter.cxx +++ b/src/SMESHGUI/SMESHGUI_Filter.cxx @@ -33,13 +33,13 @@ #include #include -OCCT_IMPLEMENT_STANDARD_RTTIEXT(SMESHGUI_Filter, VTKViewer_Filter) -OCCT_IMPLEMENT_STANDARD_RTTIEXT(SMESHGUI_PredicateFilter, SMESHGUI_Filter) -OCCT_IMPLEMENT_STANDARD_RTTIEXT(SMESHGUI_QuadrangleFilter, SMESHGUI_Filter) -OCCT_IMPLEMENT_STANDARD_RTTIEXT(SMESHGUI_TriangleFilter, SMESHGUI_Filter) -OCCT_IMPLEMENT_STANDARD_RTTIEXT(SMESHGUI_FacesFilter, SMESHGUI_Filter) -OCCT_IMPLEMENT_STANDARD_RTTIEXT(SMESHGUI_VolumesFilter, SMESHGUI_Filter) -OCCT_IMPLEMENT_STANDARD_RTTIEXT(SMESHGUI_VolumeShapeFilter, SMESHGUI_Filter) +IMPLEMENT_STANDARD_RTTIEXT(SMESHGUI_Filter, VTKViewer_Filter) +IMPLEMENT_STANDARD_RTTIEXT(SMESHGUI_PredicateFilter, SMESHGUI_Filter) +IMPLEMENT_STANDARD_RTTIEXT(SMESHGUI_QuadrangleFilter, SMESHGUI_Filter) +IMPLEMENT_STANDARD_RTTIEXT(SMESHGUI_TriangleFilter, SMESHGUI_Filter) +IMPLEMENT_STANDARD_RTTIEXT(SMESHGUI_FacesFilter, SMESHGUI_Filter) +IMPLEMENT_STANDARD_RTTIEXT(SMESHGUI_VolumesFilter, SMESHGUI_Filter) +IMPLEMENT_STANDARD_RTTIEXT(SMESHGUI_VolumeShapeFilter, SMESHGUI_Filter) /* Class : SMESHGUI_PredicateFilter diff --git a/src/SMESHGUI/SMESHGUI_Filter.h b/src/SMESHGUI/SMESHGUI_Filter.h index ec36f46d6..08a43c767 100755 --- a/src/SMESHGUI/SMESHGUI_Filter.h +++ b/src/SMESHGUI/SMESHGUI_Filter.h @@ -70,7 +70,7 @@ public: Standard_EXPORT virtual bool IsObjValid( const int ) const = 0; public: - OCCT_DEFINE_STANDARD_RTTIEXT(SMESHGUI_Filter,VTKViewer_Filter) + DEFINE_STANDARD_RTTIEXT(SMESHGUI_Filter,VTKViewer_Filter) }; /* @@ -99,7 +99,7 @@ private: SMESH::Predicate_var myPred; public: - OCCT_DEFINE_STANDARD_RTTIEXT(SMESHGUI_PredicateFilter,SMESHGUI_Filter) + DEFINE_STANDARD_RTTIEXT(SMESHGUI_PredicateFilter,SMESHGUI_Filter) }; /* @@ -121,7 +121,7 @@ public: Standard_EXPORT virtual bool IsNodeFilter() const; public: - OCCT_DEFINE_STANDARD_RTTIEXT(SMESHGUI_QuadrangleFilter,SMESHGUI_Filter) + DEFINE_STANDARD_RTTIEXT(SMESHGUI_QuadrangleFilter,SMESHGUI_Filter) }; /* @@ -143,7 +143,7 @@ public: Standard_EXPORT virtual bool IsNodeFilter() const; public: - OCCT_DEFINE_STANDARD_RTTIEXT(SMESHGUI_TriangleFilter,SMESHGUI_Filter) + DEFINE_STANDARD_RTTIEXT(SMESHGUI_TriangleFilter,SMESHGUI_Filter) }; /* @@ -165,7 +165,7 @@ public: Standard_EXPORT virtual bool IsNodeFilter() const; public: - OCCT_DEFINE_STANDARD_RTTIEXT(SMESHGUI_FacesFilter,SMESHGUI_Filter) + DEFINE_STANDARD_RTTIEXT(SMESHGUI_FacesFilter,SMESHGUI_Filter) }; /* @@ -187,7 +187,7 @@ public: Standard_EXPORT virtual bool IsNodeFilter() const; public: - OCCT_DEFINE_STANDARD_RTTIEXT(SMESHGUI_VolumesFilter,SMESHGUI_Filter) + DEFINE_STANDARD_RTTIEXT(SMESHGUI_VolumesFilter,SMESHGUI_Filter) }; /* @@ -211,7 +211,7 @@ public: Standard_EXPORT static int GetId( SMDSAbs_GeometryType geom ); public: - OCCT_DEFINE_STANDARD_RTTIEXT(SMESHGUI_VolumeShapeFilter,SMESHGUI_Filter) + DEFINE_STANDARD_RTTIEXT(SMESHGUI_VolumeShapeFilter,SMESHGUI_Filter) }; #endif // SMESHGUI_FILTER_H diff --git a/src/SMESHGUI/SMESHGUI_FilterDlg.cxx b/src/SMESHGUI/SMESHGUI_FilterDlg.cxx index 00fdedfae..d0f3a6512 100755 --- a/src/SMESHGUI/SMESHGUI_FilterDlg.cxx +++ b/src/SMESHGUI/SMESHGUI_FilterDlg.cxx @@ -798,7 +798,7 @@ void SMESHGUI_FilterTable::Table::setEditable (bool isEditable, //======================================================================= // name : SMESHGUI_FilterTable::Table::isEditable -// Purpose : Verify wheter cell is editable +// Purpose : Verify whether cell is editable //======================================================================= bool SMESHGUI_FilterTable::Table::isEditable (int row, int col) const { @@ -1571,6 +1571,7 @@ void SMESHGUI_FilterTable::updateAdditionalWidget() aCriterion == SMESH::FT_MaxElementLength3D || aCriterion == SMESH::FT_Length || aCriterion == SMESH::FT_Length2D || + aCriterion == SMESH::FT_Deflection2D || aCriterion == SMESH::FT_BallDiameter ); bool toEnable = (( isDbl && ((ComboItem*)aTable->item(aRow, 1))->value() == SMESH::FT_EqualTo) || @@ -1617,6 +1618,7 @@ const char* SMESHGUI_FilterTable::getPrecision( const int aType ) retval = "len_tol_precision"; break; case SMESH::FT_Length: case SMESH::FT_Length2D: + case SMESH::FT_Deflection2D: case SMESH::FT_MaxElementLength2D: case SMESH::FT_MaxElementLength3D: case SMESH::FT_BallDiameter: @@ -1752,6 +1754,7 @@ static QList entityTypes( const int theType ) typeIds.append( SMDSEntity_TriQuad_Hexa ); typeIds.append( SMDSEntity_Penta ); typeIds.append( SMDSEntity_Quad_Penta ); + typeIds.append( SMDSEntity_BiQuad_Penta ); typeIds.append( SMDSEntity_Hexagonal_Prism ); typeIds.append( SMDSEntity_Polyhedra ); //typeIds.append( SMDSEntity_Quad_Polyhedra ); @@ -1791,13 +1794,13 @@ void SMESHGUI_FilterTable::onCriterionChanged (const int row, const int col, con } // find out a type of item required by a new criterion and other table features - int aCriterionType = GetCriterionType(row); + int aCriterionType = GetCriterionType(row); bool anIsDoubleCriterion = false; bool anIsIntCriterion = false; bool anIsComboCriterion = false; // other features: QList comboIDs; // values to show in a combo item - int nbCompareSigns = 0; // possible values are 0,1,3 + int nbCompareSigns = 0; // possible values are 0,1,3 bool isThresholdEditable = false; // actual for "simple" item types switch ( aCriterionType ) { @@ -1810,8 +1813,7 @@ void SMESHGUI_FilterTable::onCriterionChanged (const int row, const int col, con case SMESH::FT_Area: case SMESH::FT_Volume3D: case SMESH::FT_MaxElementLength2D: - case SMESH::FT_MaxElementLength3D: - anIsDoubleCriterion = true; break; + case SMESH::FT_MaxElementLength3D: anIsDoubleCriterion = true; break; case SMESH::FT_FreeBorders: case SMESH::FT_FreeEdges: @@ -1827,7 +1829,8 @@ void SMESHGUI_FilterTable::onCriterionChanged (const int row, const int col, con case SMESH::FT_MultiConnection2D: anIsIntCriterion = true; nbCompareSigns = 3; break; case SMESH::FT_Length: - case SMESH::FT_Length2D: anIsDoubleCriterion = true; break; + case SMESH::FT_Length2D: + case SMESH::FT_Deflection2D: anIsDoubleCriterion = true; break; case SMESH::FT_BelongToMeshGroup: break; @@ -2239,6 +2242,7 @@ const QMap& SMESHGUI_FilterTable::getCriteria (const int theType) aCriteria[ SMESH::FT_BelongToGenSurface ] = tr("BELONG_TO_GENSURFACE"); aCriteria[ SMESH::FT_LyingOnGeom ] = tr("LYING_ON_GEOM"); aCriteria[ SMESH::FT_Length2D ] = tr("LENGTH2D"); + aCriteria[ SMESH::FT_Deflection2D ] = tr("DEFLECTION2D"); aCriteria[ SMESH::FT_MultiConnection2D ] = tr("MULTI2D_BORDERS"); aCriteria[ SMESH::FT_FreeFaces ] = tr("FREE_FACES"); aCriteria[ SMESH::FT_BareBorderFace ] = tr("BARE_BORDER_FACE"); diff --git a/src/SMESHGUI/SMESHGUI_GroupDlg.cxx b/src/SMESHGUI/SMESHGUI_GroupDlg.cxx index ce7f8b88a..dc1a29fa3 100644 --- a/src/SMESHGUI/SMESHGUI_GroupDlg.cxx +++ b/src/SMESHGUI/SMESHGUI_GroupDlg.cxx @@ -1113,14 +1113,14 @@ bool SMESHGUI_GroupDlg::onApply() { if ( myFilter->_is_nil() ) return false; - if (CORBA::is_nil(myGroupOnFilter)) { // creation + if (CORBA::is_nil(myGroupOnFilter)) // creation + { if (myMesh->_is_nil()) return false; myGroupOnFilter = myMesh->CreateGroupFromFilter(aType, SMESH::toUtf8(myName->text()), myFilter); - resultGroup = SMESH::SMESH_GroupBase::_narrow( myGroupOnFilter ); isCreation = true; } @@ -1134,7 +1134,7 @@ bool SMESHGUI_GroupDlg::onApply() anIsOk = true; } - if( anIsOk ) + if ( anIsOk ) { SALOMEDS::Color aColor = getGroupColor(); resultGroup->SetColor(aColor); diff --git a/src/SMESHGUI/SMESHGUI_HypothesesUtils.cxx b/src/SMESHGUI/SMESHGUI_HypothesesUtils.cxx index 12668b5bf..2ca363488 100644 --- a/src/SMESHGUI/SMESHGUI_HypothesesUtils.cxx +++ b/src/SMESHGUI/SMESHGUI_HypothesesUtils.cxx @@ -63,16 +63,20 @@ #endif #ifdef WIN32 -#define LibHandle HMODULE -#define LoadLib( name ) LoadLibrary( name ) -#define GetProc GetProcAddress -#define UnLoadLib( handle ) FreeLibrary( handle ); -#else -#define LibHandle void* -#define LoadLib( name ) dlopen( name, RTLD_LAZY | RTLD_GLOBAL ) -#define GetProc dlsym -#define UnLoadLib( handle ) dlclose( handle ); -#endif + #define LibHandle HMODULE + #define LoadLib( name ) LoadLibrary( name ) + #define GetProc GetProcAddress + #define UnLoadLib( handle ) FreeLibrary( handle ); +#else // WIN32 + #define LibHandle void* + #ifdef DYNLOAD_LOCAL + #define LoadLib( name ) dlopen( name, RTLD_LAZY | RTLD_LOCAL ) + #else // DYNLOAD_LOCAL + #define LoadLib( name ) dlopen( name, RTLD_LAZY | RTLD_GLOBAL ) + #endif // DYNLOAD_LOCAL + #define GetProc dlsym + #define UnLoadLib( handle ) dlclose( handle ); +#endif // WIN32 #ifdef _DEBUG_ static int MYDEBUG = 0; diff --git a/src/SMESHGUI/SMESHGUI_MeshEditPreview.cxx b/src/SMESHGUI/SMESHGUI_MeshEditPreview.cxx index b8522893f..7dca619fb 100644 --- a/src/SMESHGUI/SMESHGUI_MeshEditPreview.cxx +++ b/src/SMESHGUI/SMESHGUI_MeshEditPreview.cxx @@ -153,6 +153,7 @@ vtkIdType getCellType( const SMDSAbs_ElementType theType, else if ( theNbNodes == 20 ) return VTK_QUADRATIC_HEXAHEDRON; else if ( theNbNodes == 27 ) return VTK_TRIQUADRATIC_HEXAHEDRON; else if ( theNbNodes == 15 ) return VTK_QUADRATIC_WEDGE; + else if ( theNbNodes == 18 ) return VTK_BIQUADRATIC_QUADRATIC_WEDGE; else if ( theNbNodes == 13 ) return VTK_QUADRATIC_PYRAMID;//VTK_CONVEX_POINT_SET; else return VTK_EMPTY_CELL; diff --git a/src/SMESHGUI/SMESHGUI_MeshInfo.cxx b/src/SMESHGUI/SMESHGUI_MeshInfo.cxx index 610ccc08c..780ea97f8 100644 --- a/src/SMESHGUI/SMESHGUI_MeshInfo.cxx +++ b/src/SMESHGUI/SMESHGUI_MeshInfo.cxx @@ -322,7 +322,7 @@ SMESHGUI_MeshInfo::SMESHGUI_MeshInfo( QWidget* parent ) QLabel* a2DTriQuad = createField(); a2DTriQuad->setObjectName("nbQuadraticTriangle"); QLabel* a2DTriBiQuad = createField(); - a2DTriBiQuad->setObjectName("nbBiQuadraticTriangle"); + a2DTriBiQuad->setObjectName("nbBiQuadraticTriangle"); QLabel* a2DQuaLab = new QLabel( tr( "QUADRANGLES_LAB" ), this ); QLabel* a2DQuaTotal = createField(); a2DQuaTotal->setObjectName("nbQuadrangle"); @@ -386,6 +386,8 @@ SMESHGUI_MeshInfo::SMESHGUI_MeshInfo( QWidget* parent ) a3DPriLin->setObjectName("nbLinearPrism"); QLabel* a3DPriQuad = createField(); a3DPriQuad->setObjectName("nbQuadraticPrism"); + QLabel* a3DPriBiQuad = createField(); + a3DPriBiQuad->setObjectName("nbBiQuadraticPrism"); QLabel* a3DHexPriLab = new QLabel( tr( "HEX_PRISMS_LAB" ), this ); QLabel* a3DHexPriTotal = createField(); a3DHexPriTotal->setObjectName("nbHexagonalPrism"); @@ -397,7 +399,7 @@ SMESHGUI_MeshInfo::SMESHGUI_MeshInfo( QWidget* parent ) myWidgets[ index++ ] << a3DTetLab << a3DTetTotal << a3DTetLin << a3DTetQuad; myWidgets[ index++ ] << a3DHexLab << a3DHexTotal << a3DHexLin << a3DHexQuad << a3DHexBiQuad; myWidgets[ index++ ] << a3DPyrLab << a3DPyrTotal << a3DPyrLin << a3DPyrQuad; - myWidgets[ index++ ] << a3DPriLab << a3DPriTotal << a3DPriLin << a3DPriQuad; + myWidgets[ index++ ] << a3DPriLab << a3DPriTotal << a3DPriLin << a3DPriQuad << a3DPriBiQuad; myWidgets[ index++ ] << a3DHexPriLab << a3DHexPriTotal; myWidgets[ index++ ] << a3DPolLab << a3DPolTotal; @@ -491,6 +493,7 @@ SMESHGUI_MeshInfo::SMESHGUI_MeshInfo( QWidget* parent ) l->addWidget( a3DPriTotal, 24, 1 ); l->addWidget( a3DPriLin, 24, 2 ); l->addWidget( a3DPriQuad, 24, 3 ); + l->addWidget( a3DPriBiQuad, 24, 4 ); l->addWidget( a3DHexPriLab, 25, 0 ); l->addWidget( a3DHexPriTotal, 25, 1 ); l->addWidget( a3DPolLab, 26, 0 ); @@ -581,10 +584,10 @@ void SMESHGUI_MeshInfo::showInfo( SMESH::SMESH_IDSource_ptr obj ) long nbTetrahedrons = info[SMDSEntity_Tetra] + info[SMDSEntity_Quad_Tetra]; long nbHexahedrons = info[SMDSEntity_Hexa] + info[SMDSEntity_Quad_Hexa] + info[SMDSEntity_TriQuad_Hexa]; long nbPyramids = info[SMDSEntity_Pyramid] + info[SMDSEntity_Quad_Pyramid]; - long nbPrisms = info[SMDSEntity_Penta] + info[SMDSEntity_Quad_Penta]; + long nbPrisms = info[SMDSEntity_Penta] + info[SMDSEntity_Quad_Penta] + info[SMDSEntity_BiQuad_Penta]; long nb3DLinear = info[SMDSEntity_Tetra] + info[SMDSEntity_Hexa] + info[SMDSEntity_Pyramid] + info[SMDSEntity_Penta] + info[SMDSEntity_Polyhedra] + info[SMDSEntity_Hexagonal_Prism]; long nb3DQuadratic = info[SMDSEntity_Quad_Tetra] + info[SMDSEntity_Quad_Hexa] + info[SMDSEntity_Quad_Pyramid] + info[SMDSEntity_Quad_Penta]; - long nb3DBiQuadratic = info[SMDSEntity_TriQuad_Hexa]; + long nb3DBiQuadratic = info[SMDSEntity_TriQuad_Hexa] + info[SMDSEntity_BiQuad_Penta]; long nb3DTotal = nb3DLinear + nb3DQuadratic + nb3DBiQuadratic; myWidgets[i3D][iTotal] ->setProperty( "text", QString::number( nb3DTotal )); myWidgets[i3D][iLinear] ->setProperty( "text", QString::number( nb3DLinear )); @@ -603,6 +606,7 @@ void SMESHGUI_MeshInfo::showInfo( SMESH::SMESH_IDSource_ptr obj ) myWidgets[i3DPrisms][iTotal] ->setProperty( "text", QString::number( nbPrisms )); myWidgets[i3DPrisms][iLinear] ->setProperty( "text", QString::number( info[SMDSEntity_Penta] )); myWidgets[i3DPrisms][iQuadratic] ->setProperty( "text", QString::number( info[SMDSEntity_Quad_Penta] )); + myWidgets[i3DPrisms][iBiQuadratic] ->setProperty( "text", QString::number( info[SMDSEntity_BiQuad_Penta] )); myWidgets[i3DHexaPrisms][iTotal] ->setProperty( "text", QString::number( info[SMDSEntity_Hexagonal_Prism] )); myWidgets[i3DPolyhedrons][iTotal] ->setProperty( "text", QString::number( info[SMDSEntity_Polyhedra] )); long nbElemTotal = info[SMDSEntity_0D] + info[SMDSEntity_Ball] + nbEdges + nb2DTotal + nb3DTotal; @@ -937,7 +941,7 @@ void SMESHGUI_MeshInfo::saveInfo( QTextStream &out ) \param parent parent widget */ SMESHGUI_ElemInfo::SMESHGUI_ElemInfo( QWidget* parent ) -: QWidget( parent ), myActor( 0 ), myIsElement( -1 ) + : QWidget( parent ), myActor( 0 ), myIsElement( -1 ) { myFrame = new QWidget( this ); myExtra = new ExtraWidget( this ); @@ -962,11 +966,13 @@ SMESHGUI_ElemInfo::~SMESHGUI_ElemInfo() \brief Set mesh data source (actor) \param actor mesh object actor */ -void SMESHGUI_ElemInfo::setSource( SMESH_Actor* actor ) +void SMESHGUI_ElemInfo::setSource( SMESH_Actor* actor, SMESH::SMESH_IDSource_var obj ) { if ( myActor != actor ) { myActor = actor; myIsElement = -1; + SMESH::SMESH_Mesh_var mesh = obj->GetMesh(); + myMeshHasShape = ( !mesh->_is_nil() && mesh->HasShapeToMesh() ); clear(); } } @@ -1159,7 +1165,7 @@ void SMESHGUI_ElemInfo::updateControls() \param parent parent widget */ SMESHGUI_SimpleElemInfo::SMESHGUI_SimpleElemInfo( QWidget* parent ) -: SMESHGUI_ElemInfo( parent ) + : SMESHGUI_ElemInfo( parent ) { myInfo = new QTextBrowser( frame() ); QVBoxLayout* l = new QVBoxLayout( frame() ); @@ -1174,12 +1180,12 @@ SMESHGUI_SimpleElemInfo::SMESHGUI_SimpleElemInfo( QWidget* parent ) void SMESHGUI_SimpleElemInfo::information( const QList& ids ) { clearInternal(); - + if ( actor() ) { int grp_details = SMESHGUI::resourceMgr()->booleanValue( "SMESH", "elem_info_grp_details", false ); int precision = SMESHGUI::resourceMgr()->integerValue( "SMESH", "length_precision", 6 ); int cprecision = -1; - if ( SMESHGUI::resourceMgr()->booleanValue( "SMESH", "use_precision", false )) + if ( SMESHGUI::resourceMgr()->booleanValue( "SMESH", "use_precision", false )) cprecision = SMESHGUI::resourceMgr()->integerValue( "SMESH", "controls_precision", -1 ); foreach ( long id, ids ) { if ( !isElements() ) { @@ -1224,7 +1230,7 @@ void SMESHGUI_SimpleElemInfo::information( const QList& ids ) myInfo->append( QString( "%1" ).arg( SMESHGUI_ElemInfo::tr( "FREE_NODE" )).arg( id )); } // node position - SMESH::SMESH_Mesh_ptr aMeshPtr = actor()->GetObject()->GetMeshServer(); + SMESH::SMESH_Mesh_ptr aMeshPtr = actor()->GetObject()->GetMeshServer(); if ( !CORBA::is_nil( aMeshPtr )) { SMESH::NodePosition_var pos = aMeshPtr->GetNodePosition( id ); int shapeID = pos->shapeID; @@ -1240,8 +1246,8 @@ void SMESHGUI_SimpleElemInfo::information( const QList& ids ) case GEOM::FACE: shapeType = SMESHGUI_ElemInfo::tr( "GEOM_FACE" ); if ( pos->params.length() == 2 ) { - u = pos->params[0]; - v = pos->params[1]; + u = pos->params[0]; + v = pos->params[1]; } break; case GEOM::VERTEX: @@ -1285,7 +1291,7 @@ void SMESHGUI_SimpleElemInfo::information( const QList& ids ) SMESH::SMESH_Group_var aStdGroup = SMESH::SMESH_Group::_narrow( aGrp ); SMESH::SMESH_GroupOnGeom_var aGeomGroup = SMESH::SMESH_GroupOnGeom::_narrow( aGrp ); SMESH::SMESH_GroupOnFilter_var aFltGroup = SMESH::SMESH_GroupOnFilter::_narrow( aGrp ); - + // type : group on geometry, standalone group, group on filter if ( !CORBA::is_nil( aStdGroup )) { myInfo->append( QString( " - %1: %2" ).arg( SMESHGUI_AddInfo::tr( "TYPE" )). @@ -1305,11 +1311,11 @@ void SMESHGUI_SimpleElemInfo::information( const QList& ids ) myInfo->append( QString( " - %1: %2" ).arg( SMESHGUI_AddInfo::tr( "TYPE" )). arg( SMESHGUI_AddInfo::tr( "GROUP_ON_FILTER" )) ); } - + // size myInfo->append( QString( " - %1: %2" ).arg( SMESHGUI_AddInfo::tr( "SIZE" )). arg( QString::number( aGrp->Size() )) ); - + // color SALOMEDS::Color color = aGrp->GetColor(); myInfo->append( QString( " - %1: %2" ).arg( SMESHGUI_AddInfo::tr( "COLOR" )). @@ -1322,11 +1328,11 @@ void SMESHGUI_SimpleElemInfo::information( const QList& ids ) else { // // show element info - // + // const SMDS_MeshElement* e = actor()->GetObject()->GetMesh()->FindElement( id ); SMESH::Controls::NumericalFunctorPtr afunctor; if ( !e ) return; - + // Element ID && Type QString stype; switch( e->GetType() ) { @@ -1340,7 +1346,7 @@ void SMESHGUI_SimpleElemInfo::information( const QList& ids ) stype = SMESHGUI_ElemInfo::tr( "FACE" ); break; case SMDSAbs_Volume: stype = SMESHGUI_ElemInfo::tr( "VOLUME" ); break; - default: + default: break; } if ( stype.isEmpty() ) return; @@ -1374,13 +1380,14 @@ void SMESHGUI_SimpleElemInfo::information( const QList& ids ) gtype = SMESHGUI_ElemInfo::tr( "HEXAHEDRON" ); break; case SMDSEntity_Penta: case SMDSEntity_Quad_Penta: + case SMDSEntity_BiQuad_Penta: gtype = SMESHGUI_ElemInfo::tr( "PRISM" ); break; case SMDSEntity_Hexagonal_Prism: gtype = SMESHGUI_ElemInfo::tr( "HEX_PRISM" ); break; case SMDSEntity_Polyhedra: case SMDSEntity_Quad_Polyhedra: gtype = SMESHGUI_ElemInfo::tr( "POLYHEDRON" ); break; - default: + default: break; } if ( !gtype.isEmpty() ) @@ -1439,53 +1446,58 @@ void SMESHGUI_SimpleElemInfo::information( const QList& ids ) afunctor.reset( new SMESH::Controls::Length() ); afunctor->SetMesh( actor()->GetObject()->GetMesh() ); afunctor->SetPrecision( cprecision ); - myInfo->append( QString( "- %1: %2" ).arg( tr( "LENGTH_EDGES" )).arg( afunctor->GetValue( id )) ); + myInfo->append( QString( "- %1: %2" ).arg( tr( "LENGTH_EDGES" )).arg( afunctor->GetValue( id )) ); } if( e->GetType() == SMDSAbs_Face ) { //Area afunctor.reset( new SMESH::Controls::Area() ); afunctor->SetMesh( actor()->GetObject()->GetMesh() ); - afunctor->SetPrecision( cprecision ); + afunctor->SetPrecision( cprecision ); myInfo->append( QString( "- %1: %2" ).arg( tr( "AREA_ELEMENTS" )).arg( afunctor->GetValue( id )) ); //Taper afunctor.reset( new SMESH::Controls::Taper() ); - afunctor->SetMesh( actor()->GetObject()->GetMesh() ); + afunctor->SetMesh( actor()->GetObject()->GetMesh() ); afunctor->SetPrecision( cprecision ); myInfo->append( QString( "- %1: %2" ).arg( tr( "TAPER_ELEMENTS" )).arg( afunctor->GetValue( id )) ); //AspectRatio2D afunctor.reset( new SMESH::Controls::AspectRatio() ); afunctor->SetMesh( actor()->GetObject()->GetMesh() ); myInfo->append( QString( "- %1: %2" ).arg( tr( "ASPECTRATIO_ELEMENTS" )).arg( afunctor->GetValue( id )) ); - //Minimum angle + //Minimum angle afunctor.reset( new SMESH::Controls::MinimumAngle() ); afunctor->SetMesh( actor()->GetObject()->GetMesh() ); afunctor->SetPrecision( cprecision ); myInfo->append( QString( "- %1: %2" ).arg( tr( "MINIMUMANGLE_ELEMENTS" )).arg( afunctor->GetValue( id )) ); - //Wraping angle + //Warping angle afunctor.reset( new SMESH::Controls::Warping() ); afunctor->SetMesh( actor()->GetObject()->GetMesh() ); afunctor->SetPrecision( cprecision ); myInfo->append( QString( "- %1: %2" ).arg( tr( "WARP_ELEMENTS" )).arg( afunctor->GetValue( id )) ); - //Skew + //Skew afunctor.reset( new SMESH::Controls::Skew() ); afunctor->SetMesh( actor()->GetObject()->GetMesh() ); afunctor->SetPrecision( cprecision ); myInfo->append( QString( "- %1: %2" ).arg( tr( "SKEW_ELEMENTS" )).arg( afunctor->GetValue( id )) ); - //ElemDiam2D + //ElemDiam2D afunctor.reset( new SMESH::Controls::MaxElementLength2D() ); afunctor->SetMesh( actor()->GetObject()->GetMesh() ); + afunctor->SetPrecision( cprecision ); myInfo->append( QString( "- %1: %2" ).arg( tr( "MAX_ELEMENT_LENGTH_2D" )).arg( afunctor->GetValue( id )) ); + //min edge length + afunctor.reset( new SMESH::Controls::Length2D() ); + afunctor->SetMesh( actor()->GetObject()->GetMesh() ); + myInfo->append( QString( "- %1: %2" ).arg( tr( "MIN_ELEM_EDGE" )).arg( afunctor->GetValue( id )) ); } if( e->GetType() == SMDSAbs_Volume ) { //AspectRatio3D afunctor.reset( new SMESH::Controls::AspectRatio3D() ); afunctor->SetMesh( actor()->GetObject()->GetMesh() ); myInfo->append( QString( "- %1: %2" ).arg( tr( "ASPECTRATIO_3D_ELEMENTS" )).arg( afunctor->GetValue( id )) ); - //Volume + //Volume afunctor.reset( new SMESH::Controls::Volume() ); afunctor->SetMesh( actor()->GetObject()->GetMesh() ); myInfo->append( QString( "- %1: %2" ).arg( tr( "VOLUME_3D_ELEMENTS" )).arg( afunctor->GetValue( id )) ); - //ElementDiameter3D + //ElementDiameter3D afunctor.reset( new SMESH::Controls::Volume() ); afunctor->SetMesh( actor()->GetObject()->GetMesh() ); myInfo->append( QString( "- %1: %2" ).arg( tr( "MAX_ELEMENT_LENGTH_3D" )).arg( afunctor->GetValue( id )) ); @@ -1496,7 +1508,7 @@ void SMESHGUI_SimpleElemInfo::information( const QList& ids ) // Gravity center XYZ gc = gravityCenter( e ); myInfo->append( QString( "%1: (%2, %3, %4)" ).arg( SMESHGUI_ElemInfo::tr( "GRAVITY_CENTER" )).arg( gc.x() ).arg( gc.y() ).arg( gc.z() )); - + // Normal vector if( e->GetType() == SMDSAbs_Face ) { XYZ gc = normal( e ); @@ -1505,7 +1517,7 @@ void SMESHGUI_SimpleElemInfo::information( const QList& ids ) // Element position if ( e->GetType() >= SMDSAbs_Edge && e->GetType() <= SMDSAbs_Volume ) { - SMESH::SMESH_Mesh_ptr aMesh = actor()->GetObject()->GetMeshServer(); + SMESH::SMESH_Mesh_ptr aMesh = actor()->GetObject()->GetMeshServer(); if ( !CORBA::is_nil( aMesh )) { SMESH::ElementPosition pos = aMesh->GetElementPosition( id ); int shapeID = pos.shapeID; @@ -1545,7 +1557,7 @@ void SMESHGUI_SimpleElemInfo::information( const QList& ids ) SMESH::SMESH_Group_var aStdGroup = SMESH::SMESH_Group::_narrow( aGrp ); SMESH::SMESH_GroupOnGeom_var aGeomGroup = SMESH::SMESH_GroupOnGeom::_narrow( aGrp ); SMESH::SMESH_GroupOnFilter_var aFltGroup = SMESH::SMESH_GroupOnFilter::_narrow( aGrp ); - + // type : group on geometry, standalone group, group on filter if ( !CORBA::is_nil( aStdGroup )) { myInfo->append( QString( " - %1: %2" ).arg( SMESHGUI_AddInfo::tr( "TYPE" )). @@ -1565,10 +1577,10 @@ void SMESHGUI_SimpleElemInfo::information( const QList& ids ) myInfo->append( QString( " - %1: %2" ).arg( SMESHGUI_AddInfo::tr( "TYPE" )). arg( SMESHGUI_AddInfo::tr( "GROUP_ON_FILTER" )) ); } - + myInfo->append( QString( " - %1: %2" ).arg( SMESHGUI_AddInfo::tr( "SIZE" )). arg( QString::number( aGrp->Size() )) ); - + // color SALOMEDS::Color color = aGrp->GetColor(); myInfo->append( QString( " - %1: %2" ).arg( SMESHGUI_AddInfo::tr( "COLOR" )). @@ -1647,7 +1659,7 @@ QWidget* SMESHGUI_TreeElemInfo::ItemDelegate::createEditor( QWidget* parent, con \param parent parent widget */ SMESHGUI_TreeElemInfo::SMESHGUI_TreeElemInfo( QWidget* parent ) -: SMESHGUI_ElemInfo( parent ) + : SMESHGUI_ElemInfo( parent ) { myInfo = new QTreeWidget( frame() ); myInfo->setColumnCount( 2 ); @@ -1896,6 +1908,7 @@ void SMESHGUI_TreeElemInfo::information( const QList& ids ) gtype = SMESHGUI_ElemInfo::tr( "HEXAHEDRON" ); break; case SMDSEntity_Penta: case SMDSEntity_Quad_Penta: + case SMDSEntity_BiQuad_Penta: gtype = SMESHGUI_ElemInfo::tr( "PRISM" ); break; case SMDSEntity_Hexagonal_Prism: gtype = SMESHGUI_ElemInfo::tr( "HEX_PRISM" ); break; @@ -1986,7 +1999,7 @@ void SMESHGUI_TreeElemInfo::information( const QList& ids ) QTreeWidgetItem* taperlItem = createItem( cntrItem, Bold ); taperlItem->setText( 0, tr( "TAPER_ELEMENTS" )); taperlItem->setText( 1, QString( "%1" ).arg( afunctor->GetValue( id )) ); - //Wraping angle + //Warping angle afunctor.reset( new SMESH::Controls::Warping() ); afunctor->SetMesh( actor()->GetObject()->GetMesh() ); afunctor->SetPrecision( cprecision ); @@ -2020,6 +2033,15 @@ void SMESHGUI_TreeElemInfo::information( const QList& ids ) skewItem->setText( 0, tr( "SKEW_ELEMENTS" )); skewItem->setText( 1, QString( "%1" ).arg( afunctor->GetValue( id )) ); } + //Deflection + if ( hasShapeToMesh() ) + { + afunctor.reset( new SMESH::Controls::Deflection2D() ); + afunctor->SetMesh( actor()->GetObject()->GetMesh() ); + QTreeWidgetItem* deflItem = createItem( cntrItem, Bold ); + deflItem->setText( 0, tr( "DEFLECTION_2D" )); + deflItem->setText( 1, QString( "%1" ).arg( afunctor->GetValue( id )) ); + } //ElemDiam2D if ( !e->IsPoly() ) { @@ -2054,6 +2076,13 @@ void SMESHGUI_TreeElemInfo::information( const QList& ids ) diam3Item->setText( 1, QString( "%1" ).arg( afunctor->GetValue( id )) ); } + //min edge length + afunctor.reset( new SMESH::Controls::Length2D() ); + afunctor->SetMesh( actor()->GetObject()->GetMesh() ); + QTreeWidgetItem* minEdgeItem = createItem( cntrItem, Bold ); + minEdgeItem->setText( 0, tr( "MIN_ELEM_EDGE" )); + minEdgeItem->setText( 1, QString( "%1" ).arg( afunctor->GetValue( id )) ); + // gravity center XYZ gc = gravityCenter( e ); QTreeWidgetItem* gcItem = createItem( elemItem, Bold ); @@ -2380,7 +2409,7 @@ void GrpComputor::compute() \param parent parent widget */ SMESHGUI_AddInfo::SMESHGUI_AddInfo( QWidget* parent ) -: QTreeWidget( parent ) + : QTreeWidget( parent ) { setColumnCount( 2 ); header()->setStretchLastSection( true ); @@ -2984,7 +3013,7 @@ void SMESHGUI_MeshInfoDlg::showInfo( const Handle(SALOME_InteractiveObject)& IO SMESH::GetNameOfSelectedElements( selector, IO, ID ) : SMESH::GetNameOfSelectedNodes( selector, IO, ID ); } - myElemInfo->setSource( myActor ) ; + myElemInfo->setSource( myActor, obj ) ; if ( nb > 0 ) { myID->setText( ID.trimmed() ); QSet ids; @@ -3615,12 +3644,12 @@ void SMESHGUI_CtrlInfo::showInfo( SMESH::SMESH_IDSource_ptr obj ) computeOverConstrainedVolumesInfo(); // aspect Ratio 3D histogram computeAspectRatio3D(); - } - else { - myButtons[7]->setEnabled( true ); - myButtons[8]->setEnabled( true ); - myButtons[9]->setEnabled( true ); - } + } + else { + myButtons[7]->setEnabled( true ); + myButtons[8]->setEnabled( true ); + myButtons[9]->setEnabled( true ); + } #ifdef DISABLE_PLOT2DVIEWER myMainLayout->setRowStretch(17,0); for( int i=35; i<=37; i++) @@ -3848,7 +3877,7 @@ void SMESHGUI_CtrlInfo::saveInfo( QTextStream &out ) { \param parent parent widget */ SMESHGUI_CtrlInfoDlg::SMESHGUI_CtrlInfoDlg( QWidget* parent ) -: QDialog( parent ) + : QDialog( parent ) { setAttribute( Qt::WA_DeleteOnClose, true ); setWindowTitle( tr( "CTRL_INFO" )); diff --git a/src/SMESHGUI/SMESHGUI_MeshInfo.h b/src/SMESHGUI/SMESHGUI_MeshInfo.h index 4b43e1aa4..85edb6001 100644 --- a/src/SMESHGUI/SMESHGUI_MeshInfo.h +++ b/src/SMESHGUI/SMESHGUI_MeshInfo.h @@ -153,7 +153,7 @@ public: SMESHGUI_ElemInfo( QWidget* = 0 ); ~SMESHGUI_ElemInfo(); - void setSource( SMESH_Actor* ); + void setSource( SMESH_Actor*, SMESH::SMESH_IDSource_var ); void showInfo( long, bool ); void showInfo( QSet, bool ); void clear(); @@ -179,6 +179,7 @@ protected: QWidget* frame() const; SMESH_Actor* actor() const; bool isElements() const; + bool hasShapeToMesh() const { return myMeshHasShape; } virtual void information( const QList& ) = 0; virtual void clearInternal(); @@ -204,6 +205,7 @@ private: QWidget* myFrame; ExtraWidget* myExtra; int myIndex; + bool myMeshHasShape; }; class SMESHGUI_EXPORT SMESHGUI_SimpleElemInfo : public SMESHGUI_ElemInfo diff --git a/src/SMESHGUI/SMESHGUI_MeshInfosBox.cxx b/src/SMESHGUI/SMESHGUI_MeshInfosBox.cxx index 4bb587ef7..ff20b1f87 100644 --- a/src/SMESHGUI/SMESHGUI_MeshInfosBox.cxx +++ b/src/SMESHGUI/SMESHGUI_MeshInfosBox.cxx @@ -70,7 +70,7 @@ SMESHGUI_MeshInfosBox::SMESHGUI_MeshInfosBox(const bool full, QWidget* theParent myNbHexa(0), myNbLinHexa(0), myNbQuadHexa(0), myNbBiQuadHexa(0), myNbTetra(0),myNbLinTetra(0),myNbQuadTetra(0), myNbPyra(0), myNbLinPyra(0), myNbQuadPyra(0), - myNbPrism(0),myNbLinPrism(0), myNbQuadPrism(0), + myNbPrism(0),myNbLinPrism(0), myNbQuadPrism(0), myNbBiQuadPrism(0), myNbVolum(0), myNbLinVolum(0), myNbQuadVolum(0), myNbBiQuadVolum(0), myNbHexaPrism(0), myNbPolyh(0) @@ -309,6 +309,9 @@ SMESHGUI_MeshInfosBox::SMESHGUI_MeshInfosBox(const bool full, QWidget* theParent myNbQuadPrism = new QLabel( this ); l->addWidget( myNbQuadPrism, row, 3 ); // -- + myNbBiQuadPrism = new QLabel( this ); + l->addWidget( myNbBiQuadPrism, row, 4 ); + // -- row++; // increment row count // ... hexa prisms lab = new QLabel(COLONIZE(tr("SMESH_MESHINFO_HEXAPRISM")), this ); @@ -460,6 +463,7 @@ void SMESHGUI_MeshInfosBox::SetMeshInfo(const SMESH::long_array& theInfo) theInfo[SMDSEntity_TriQuad_Hexa] + theInfo[SMDSEntity_Penta] + theInfo[SMDSEntity_Quad_Penta] + + theInfo[SMDSEntity_BiQuad_Penta] + theInfo[SMDSEntity_Hexagonal_Prism] + theInfo[SMDSEntity_Polyhedra] )); myNbLinVolum ->setText( QString("%1").arg( theInfo[SMDSEntity_Tetra] + @@ -471,7 +475,8 @@ void SMESHGUI_MeshInfosBox::SetMeshInfo(const SMESH::long_array& theInfo) theInfo[SMDSEntity_Quad_Pyramid] + theInfo[SMDSEntity_Quad_Hexa] + theInfo[SMDSEntity_Quad_Penta] )); - myNbBiQuadVolum->setText( QString("%1").arg( theInfo[SMDSEntity_TriQuad_Hexa] )); + myNbBiQuadVolum->setText( QString("%1").arg( theInfo[SMDSEntity_TriQuad_Hexa] + + theInfo[SMDSEntity_BiQuad_Penta] )); if ( myFull ) { @@ -514,9 +519,11 @@ void SMESHGUI_MeshInfosBox::SetMeshInfo(const SMESH::long_array& theInfo) myNbQuadPyra ->setText( QString("%1").arg( theInfo[SMDSEntity_Quad_Pyramid] )); // prisms myNbPrism ->setText( QString("%1").arg( theInfo[SMDSEntity_Penta] + - theInfo[SMDSEntity_Quad_Penta] )); - myNbLinPrism ->setText( QString("%1").arg( theInfo[SMDSEntity_Penta] )); - myNbQuadPrism->setText( QString("%1").arg( theInfo[SMDSEntity_Quad_Penta] )); + theInfo[SMDSEntity_Quad_Penta] + + theInfo[SMDSEntity_BiQuad_Penta] )); + myNbLinPrism ->setText( QString("%1").arg( theInfo[SMDSEntity_Penta] )); + myNbQuadPrism ->setText( QString("%1").arg( theInfo[SMDSEntity_Quad_Penta] )); + myNbBiQuadPrism->setText( QString("%1").arg( theInfo[SMDSEntity_BiQuad_Penta] )); // octahedra myNbHexaPrism->setText( QString("%1").arg( theInfo[ SMDSEntity_Hexagonal_Prism ])); // polyedres diff --git a/src/SMESHGUI/SMESHGUI_MeshInfosBox.h b/src/SMESHGUI/SMESHGUI_MeshInfosBox.h index c6ecbb3cf..5671cf1d5 100644 --- a/src/SMESHGUI/SMESHGUI_MeshInfosBox.h +++ b/src/SMESHGUI/SMESHGUI_MeshInfosBox.h @@ -84,6 +84,7 @@ private: QLabel* myNbPrism; QLabel* myNbLinPrism; QLabel* myNbQuadPrism; + QLabel* myNbBiQuadPrism; QLabel* myNbVolum; QLabel* myNbLinVolum; QLabel* myNbQuadVolum; diff --git a/src/SMESHGUI/SMESHGUI_MultiEditDlg.cxx b/src/SMESHGUI/SMESHGUI_MultiEditDlg.cxx index 6820457e5..2c0ae0eda 100755 --- a/src/SMESHGUI/SMESHGUI_MultiEditDlg.cxx +++ b/src/SMESHGUI/SMESHGUI_MultiEditDlg.cxx @@ -435,7 +435,7 @@ void SMESHGUI_MultiEditDlg::onOk() //======================================================================= // name : SMESHGUI_MultiEditDlg::getIds -// Purpose : Retrive identifiers from list box or the whole object +// Purpose : Retrieve identifiers from list box or the whole object //======================================================================= SMESH::long_array_var SMESHGUI_MultiEditDlg::getIds(SMESH::SMESH_IDSource_var& obj) diff --git a/src/SMESHGUI/SMESHGUI_Operations.h b/src/SMESHGUI/SMESHGUI_Operations.h index 89f53472b..c45b9eae1 100644 --- a/src/SMESHGUI/SMESHGUI_Operations.h +++ b/src/SMESHGUI/SMESHGUI_Operations.h @@ -91,7 +91,7 @@ namespace SMESHOp { OpRemoveElemGroupPopup = 2082, // POPUP MENU - REMOVE ELEMENTS FROM GROUP OpMeshInformation = 2100, // MENU MESH - MESH INFORMATION OpWhatIs = 2101, // MENU MESH - MESH ELEMENT INFORMATION - OpStdInfo = 2102, // MENU MESH - MESH STANDART INFORMATION + OpStdInfo = 2102, // MENU MESH - MESH STANDARD INFORMATION OpFindElementByPoint = 2103, // MENU MESH - FIND ELEMENT BY POINT OpUpdate = 2200, // POPUP MENU - UPDATE // Controls -----------------------//-------------------------------- @@ -116,6 +116,7 @@ namespace SMESHOp { OpSkew = 3210, // MENU CONTROLS - SKEW OpMaxElementLength2D = 3211, // MENU CONTROLS - ELEMENT DIAMETER 2D OpEqualFace = 3212, // MENU CONTROLS - DOUBLE FACES + OpDeflection2D = 3213, // MENU CONTROLS - DEFLECTION 2D OpAspectRatio3D = 3300, // MENU CONTROLS - ASPECT RATIO 3D OpVolume = 3301, // MENU CONTROLS - VOLUME OpMaxElementLength3D = 3302, // MENU CONTROLS - ELEMENT DIAMETER 3D @@ -146,9 +147,10 @@ namespace SMESHOp { OpQuadraticTetrahedron = 4105, // MENU MODIFICATION - ADD - QUADRATIC TETRAHEDRON OpQuadraticPyramid = 4106, // MENU MODIFICATION - ADD - QUADRATIC PYRAMID OpQuadraticPentahedron = 4107, // MENU MODIFICATION - ADD - QUADRATIC PENTAHEDRON - OpQuadraticHexahedron = 4108, // MENU MODIFICATION - ADD - QUADRATIC HEXAHEDRON - OpTriQuadraticHexahedron = 4109, // MENU MODIFICATION - ADD - TRIQUADRATIC HEXAHEDRON - OpQuadraticPolygon = 4110, // MENU MODIFICATION - ADD - QUADRATIC POLYGON + OpBiQuadraticPentahedron = 4108, // MENU MODIFICATION - ADD - BIQUADRATIC PENTAHEDRON + OpQuadraticHexahedron = 4110, // MENU MODIFICATION - ADD - QUADRATIC HEXAHEDRON + OpTriQuadraticHexahedron = 4111, // MENU MODIFICATION - ADD - TRIQUADRATIC HEXAHEDRON + OpQuadraticPolygon = 4112, // MENU MODIFICATION - ADD - QUADRATIC POLYGON OpRemoveNodes = 4200, // MENU MODIFICATION - REMOVE - NODE OpRemoveElements = 4201, // MENU MODIFICATION - REMOVE - ELEMENTS OpRemoveOrphanNodes = 4202, // MENU MODIFICATION - REMOVE - ORPHAN NODES diff --git a/src/SMESHGUI/SMESHGUI_Selection.cxx b/src/SMESHGUI/SMESHGUI_Selection.cxx index 0b113839d..a8704b8b9 100644 --- a/src/SMESHGUI/SMESHGUI_Selection.cxx +++ b/src/SMESHGUI/SMESHGUI_Selection.cxx @@ -359,6 +359,7 @@ QString SMESHGUI_Selection::controlMode( int ind ) const switch( actor->GetControlMode() ) { case SMESH_Actor::eLength: mode = "eLength"; break; case SMESH_Actor::eLength2D: mode = "eLength2D"; break; + case SMESH_Actor::eDeflection2D: mode = "eDeflection2D"; break; case SMESH_Actor::eFreeEdges: mode = "eFreeEdges"; break; case SMESH_Actor::eFreeNodes: mode = "eFreeNodes"; break; case SMESH_Actor::eFreeBorders: mode = "eFreeBorders"; break; @@ -406,6 +407,11 @@ QString SMESHGUI_Selection::controlMode() const return "eNone"; } +//======================================================================= +//function : isNumFunctor +//purpose : return true if a given actor is shown using a numeric functor +//======================================================================= + bool SMESHGUI_Selection::isNumFunctor( int ind ) const { bool result = false; @@ -414,6 +420,7 @@ bool SMESHGUI_Selection::isNumFunctor( int ind ) const switch( actor->GetControlMode() ) { case SMESH_Actor::eLength: case SMESH_Actor::eLength2D: + case SMESH_Actor::eDeflection2D: case SMESH_Actor::eMultiConnection: case SMESH_Actor::eMultiConnection2D: case SMESH_Actor::eArea: @@ -437,7 +444,7 @@ bool SMESHGUI_Selection::isNumFunctor( int ind ) const //======================================================================= //function : facesOrientationMode -//purpose : +//purpose : //======================================================================= QString SMESHGUI_Selection::facesOrientationMode( int ind ) const diff --git a/src/SMESHGUI/SMESHGUI_SingleEditDlg.cxx b/src/SMESHGUI/SMESHGUI_SingleEditDlg.cxx index a95ce5648..b3c14cb52 100755 --- a/src/SMESHGUI/SMESHGUI_SingleEditDlg.cxx +++ b/src/SMESHGUI/SMESHGUI_SingleEditDlg.cxx @@ -22,6 +22,9 @@ // File : SMESHGUI_SingleEditDlg.cxx // Author : Sergey LITONIN, Open CASCADE S.A.S. + +#include + // SMESH includes // #include "SMESHGUI_SingleEditDlg.h" @@ -42,7 +45,6 @@ #include #include -#include #include #include @@ -347,9 +349,9 @@ void SMESHGUI_SingleEditDlg::onTextChange (const QString& theNewText) aList.Append(anIO); mySelectionMgr->setSelectedObjects(aList,false); - TColStd_IndexedMapOfInteger selectedIndices; - TColStd_MapOfInteger newIndices; - mySelector->GetIndex(anIO,selectedIndices); + SVTK_IndexedMapOfIds selectedIndices; + SVTK_ListOfInteger newIndices; + mySelector->GetCompositeIndex(anIO,selectedIndices); int id1, id2; if ( !getNodeIds(myEdge->text(), id1, id2) ) @@ -367,25 +369,13 @@ void SMESHGUI_SingleEditDlg::onTextChange (const QString& theNewText) if ( findTriangles(aNode1,aNode2,tria1,tria2) ) { - newIndices.Add(tria1->GetID()); - - const SMDS_MeshNode* a3Nodes[3]; - SMDS_ElemIteratorPtr it; - int edgeInd = 2, i; - for (i = 0, it = tria1->nodesIterator(); it->more(); i++) { - a3Nodes[ i ] = static_cast(it->next()); - if (i > 0 && ( (a3Nodes[ i ] == aNode1 && a3Nodes[ i - 1] == aNode2) || - (a3Nodes[ i ] == aNode2 && a3Nodes[ i - 1] == aNode1) ) ) { - edgeInd = i - 1; - break; - } - } - newIndices.Add(-edgeInd-1); + newIndices.push_back( aNode1->GetID() ); + newIndices.push_back( aNode2->GetID() ); myOkBtn->setEnabled(true); myApplyBtn->setEnabled(true); } - mySelector->AddOrRemoveIndex(anIO,newIndices, false); + mySelector->AddOrRemoveCompositeIndex(anIO, newIndices, false); SMESH::GetViewWindow(mySMESHGUI)->highlight( anIO, true, true ); } } @@ -420,7 +410,17 @@ void SMESHGUI_SingleEditDlg::onSelectionDone() if(SMDS_Mesh* aMesh = aVisualObj->GetMesh()) { const SMDS_MeshElement* tria[2]; - if( SMESH::GetEdgeNodes( mySelector, aVisualObj, anId1, anId2 ) >= 1 && + + bool valid = false; + SVTK_IndexedMapOfIds anIds; + mySelector->GetCompositeIndex(anIO,anIds); + if( anIds.Extent() == 1 && anIds(1).size() == 2 ) { + anId1 = anIds(1)[0]; + anId2 = anIds(1)[1]; + valid = true; + } + + if( valid && findTriangles( aMesh->FindNode( anId1 ), aMesh->FindNode( anId2 ), tria[0],tria[1] ) ) { QString aText = QString("%1-%2").arg(anId1).arg(anId2); @@ -523,6 +523,7 @@ bool SMESHGUI_SingleEditDlg::onApply() // update actor if (aResult) { mySelector->ClearIndex(); + mySelector->ClearCompositeIndex(); mySelectionMgr->setSelectedObjects(aList, false); onSelectionDone(); SMESH::UpdateView(); diff --git a/src/SMESHGUI/SMESHGUI_VTKUtils.cxx b/src/SMESHGUI/SMESHGUI_VTKUtils.cxx index 98fcb550d..eac67620e 100644 --- a/src/SMESHGUI/SMESHGUI_VTKUtils.cxx +++ b/src/SMESHGUI/SMESHGUI_VTKUtils.cxx @@ -350,7 +350,7 @@ namespace SMESH } if ( objModified ) { - // PAL16631. Mesurements showed that to show aVisualObj in SHADING(default) mode, + // PAL16631. Measurements showed that to show aVisualObj in SHADING(default) mode, // ~5 times more memory is used than it occupies. // Warn the user if there is less free memory than 30 sizes of a grid // TODO: estimate memory usage in other modes and take current mode into account @@ -384,7 +384,7 @@ namespace SMESH /*! Return active view window, if it instantiates SVTK_ViewWindow class, - * overwise find or create corresponding view window, make it active and return it. + * otherwise find or create corresponding view window, make it active and return it. * \note Active VVTK_ViewWindow can be returned, because it inherits SVTK_ViewWindow. */ SVTK_ViewWindow* GetViewWindow (const SalomeApp_Module* theModule, diff --git a/src/SMESHGUI/SMESH_images.ts b/src/SMESHGUI/SMESH_images.ts index 9531e409f..27ce2523f 100644 --- a/src/SMESHGUI/SMESH_images.ts +++ b/src/SMESHGUI/SMESH_images.ts @@ -211,6 +211,10 @@ ICON_DLG_QUADRATIC_PENTAHEDRON mesh_quad_pentahedron.png + + ICON_DLG_BIQUADRATIC_PENTAHEDRON + mesh_quad_pentahedron.png + ICON_DLG_QUADRATIC_PYRAMID mesh_quad_pyramid.png @@ -343,6 +347,10 @@ ICON_LENGTH_2D mesh_length_2d.png + + ICON_DEFLECTION_2D + mesh_deflection.png + ICON_MAP mesh_pattern.png diff --git a/src/SMESHGUI/SMESH_msg_en.ts b/src/SMESHGUI/SMESH_msg_en.ts index c7ec562eb..1d4ab3789 100644 --- a/src/SMESHGUI/SMESH_msg_en.ts +++ b/src/SMESHGUI/SMESH_msg_en.ts @@ -39,6 +39,10 @@ CGNS_FILES_FILTER CGNS files + + CGNS_EXPORT_ELEMS_BY_TYPE + Group elements by type + GMF_ASCII_FILES_FILTER GMF ASCII files @@ -99,6 +103,10 @@ MIN_DIAG_ELEMENTS Minimum diagonal + + MIN_ELEM_EDGE + Minimum Edge Length + ASPECTRATIO_3D_ELEMENTS Aspect Ratio 3D @@ -220,6 +228,10 @@ LENGTH2D_EDGES Length 2D + + DEFLECTION2D_FACES + Deflection 2D + LENGTH_EDGES Length @@ -236,6 +248,10 @@ MAX_ELEMENT_LENGTH_3D Element Diameter 3D + + DEFLECTION_2D + Deflection 2D + MEN_ADD Add @@ -688,6 +704,10 @@ MEN_LENGTH_2D Length 2D + + MEN_DEFLECTION_2D + Deflection 2D + MEN_MAP Pattern Mapping @@ -888,6 +908,10 @@ MEN_QUADRATIC_PENTAHEDRON Quadratic Pentahedron + + MEN_BIQUADRATIC_PENTAHEDRON + BiQuadratic Pentahedron + MEN_QUADRATIC_PYRAMID Quadratic Pyramid @@ -1366,6 +1390,10 @@ Please enter correct values and try again SMESH_ADD_QUADRATIC_PENTAHEDRON_TITLE Add Quadratic Pentahedron + + SMESH_ADD_BIQUADRATIC_PENTAHEDRON_TITLE + Add BiQuadratic Pentahedron + SMESH_ADD_QUADRATIC_PYRAMID_TITLE Add Quadratic Pyramid @@ -2113,7 +2141,7 @@ Check algorithm documentation for supported geometry SMESH_MESHINFO_ALL_TYPES - Heterogenous + Heterogeneous SMESH_MESHINFO_EDGES @@ -2519,10 +2547,18 @@ Check algorithm documentation for supported geometry SMESH_QUADRATIC_PENTAHEDRON Quadratic Pentahedron + + SMESH_BIQUADRATIC_PENTAHEDRON + BiQuadratic Pentahedron + SMESH_QUADRATIC_PENTAHEDRONS Quadratic Pentahedrons + + SMESH_BIQUADRATIC_PENTAHEDRONS + BiQuadratic Pentahedrons + SMESH_QUADRATIC_PYRAMID Quadratic Pyramid @@ -3251,6 +3287,10 @@ Use Display Entity menu command to show them. STB_LENGTH_2D Length 2D + + STB_DEFLECTION_2D + Deflection 2D + STB_MAP Pattern mapping @@ -3375,6 +3415,10 @@ Use Display Entity menu command to show them. STB_QUADRATIC_PENTAHEDRON Quadratic Pentahedron + + STB_BIQUADRATIC_PENTAHEDRON + BiQuadratic Pentahedron + STB_QUADRATIC_PYRAMID Quadratic Pyramid @@ -3927,6 +3971,10 @@ Use Display Entity menu command to show them. TOP_LENGTH_2D Length 2D + + TOP_DEFLECTION_2D + Deflection 2D + TOP_MAP Pattern mapping @@ -4051,6 +4099,10 @@ Use Display Entity menu command to show them. TOP_QUADRATIC_PENTAHEDRON Quadratic Pentahedron + + TOP_BIQUADRATIC_PENTAHEDRON + BiQuadratic Pentahedron + TOP_QUADRATIC_PYRAMID Quadratic Pyramid @@ -4888,6 +4940,10 @@ Please, create VTK viewer and try again SMESH_ADD_QUADRATIC_PENTAHEDRON Add Quadratic Pentahedron + + SMESH_ADD_BIQUADRATIC_PENTAHEDRON + Add BiQuadratic Pentahedron + SMESH_ADD_QUADRATIC_PYRAMID Add Quadratic Pyramid @@ -5830,6 +5886,10 @@ Please enter correct value and try again LENGTH2D Length 2D + + DEFLECTION2D + Deflection 2D + LESS_THAN Less than @@ -6018,18 +6078,22 @@ Please enter correct value and try again ENTITY_TYPE_21 - OCTA12 + PENTA18 ENTITY_TYPE_22 - POLYEDRE + OCTA12 ENTITY_TYPE_23 - QPOLYEDRE + POLYEDRE ENTITY_TYPE_24 + QPOLYEDRE + + + ENTITY_TYPE_25 BALL diff --git a/src/SMESHGUI/SMESH_msg_fr.ts b/src/SMESHGUI/SMESH_msg_fr.ts index 5e4f1b97b..5418e81c6 100755 --- a/src/SMESHGUI/SMESH_msg_fr.ts +++ b/src/SMESHGUI/SMESH_msg_fr.ts @@ -39,6 +39,10 @@ CGNS_FILES_FILTER Fichiers CGNS + + CGNS_EXPORT_ELEMS_BY_TYPE + Groupe les éléments par type + GMF_ASCII_FILES_FILTER Fichiers GMF ASCII @@ -384,6 +388,22 @@ MEN_DEL_GROUP Supprimer les groupes et leur contenu + + MEN_ADD_TO_GROUP + Ajoute dans le groupe + + + MEN_REMOVE_FROM_GROUP + Supprime du groupe + + + STB_ADD_TO_GROUP + Ajoute dans le groupe les éléments sélectionnés + + + STB_REMOVE_FROM_GROUP + Supprime du groupe les éléments sélectionnés + MEN_FACE_ORIENTATION Orientation des faces @@ -872,6 +892,10 @@ MEN_QUADRATIC_PENTAHEDRON Pentaèdre quadratique + + MEN_BIQUADRATIC_PENTAHEDRON + Pentaèdre biquadratique + MEN_QUADRATIC_PYRAMID Pyramide quadratique @@ -1350,6 +1374,10 @@ Merci de les corriger, puis essayez de nouveau SMESH_ADD_QUADRATIC_PENTAHEDRON_TITLE Ajouter un pentaèdre quadratique + + SMESH_ADD_BIQUADRATIC_PENTAHEDRON_TITLE + Ajouter un pentaèdre biquadratique + SMESH_ADD_QUADRATIC_PYRAMID_TITLE Ajouter une pyramide quadratique @@ -2503,10 +2531,18 @@ Référez-vous à la documentation sur l'algorithme et la géométrie suppo SMESH_QUADRATIC_PENTAHEDRON Pentaèdre quadratique + + SMESH_BIQUADRATIC_PENTAHEDRON + Pentaèdre biquadratique + SMESH_QUADRATIC_PENTAHEDRONS Pentaèdres quadratiques + + SMESH_BIQUADRATIC_PENTAHEDRONS + Pentaèdres biquadratiques + SMESH_QUADRATIC_PYRAMID Pyramide quadratique @@ -3360,6 +3396,10 @@ Utilisez le menu "Visualiser une entité" pour les afficher. STB_QUADRATIC_PENTAHEDRON Pentaèdre quadratique + + STB_BIQUADRATIC_PENTAHEDRON + Pentaèdre biquadratique + STB_QUADRATIC_PYRAMID Pyramide quadratique @@ -4036,6 +4076,10 @@ Utilisez le menu "Visualiser une entité" pour les afficher. TOP_QUADRATIC_PENTAHEDRON Pentaèdre quadratique + + TOP_BIQUADRATIC_PENTAHEDRON + Pentaèdre biquadratique + TOP_QUADRATIC_PYRAMID Pyramide quadratique @@ -4873,6 +4917,10 @@ Ouvrez une fenêtre VTK et essayez de nouveau SMESH_ADD_QUADRATIC_PENTAHEDRON Ajouter un pentaèdre quadratique + + SMESH_ADD_BIQUADRATIC_PENTAHEDRON + Ajouter un pentaèdre biquadratique + SMESH_ADD_QUADRATIC_PYRAMID Ajouter une pyramide quadratique @@ -5302,6 +5350,10 @@ Choisissez un groupe et essayez de nouveau SEPARATE_CORNERS_AND_MEDIUM Pas de fusion du coin et des noeuds moyens des cellules quadratiques + + AVOID_MAKING_HOLES + Evite de créer des trous + KEEP_NODES Les noeuds à conserver pendant la fusion @@ -6001,18 +6053,22 @@ Entrez une valeur correcte et essayez de nouveau ENTITY_TYPE_21 - OCTA12 + PENTA18 ENTITY_TYPE_22 - POLYEDRE + OCTA12 ENTITY_TYPE_23 - QPOLYEDRE + POLYEDRE ENTITY_TYPE_24 + QPOLYEDRE + + + ENTITY_TYPE_25 BALL @@ -6972,6 +7028,14 @@ Il y a trop peu de points dans le fichier SMESH_CREATE_GROUP_FROM_GEOM Créer des groupes à partir de la géométrie + + ELEMENTS + Eléments + + + ELEMENTS_TOOLTIP + Pas d'éléments 0D + SMESHGUI_MeshOrderDlg @@ -7402,6 +7466,10 @@ en raison de leurs types incompatibles: ELEM_MODE Elément + + SHOW_IDS + Montre les IDs + BUT_DUMP_MESH &Dump diff --git a/src/SMESHGUI/SMESH_msg_ja.ts b/src/SMESHGUI/SMESH_msg_ja.ts index c877ebeb7..5ea6dbe1d 100644 --- a/src/SMESHGUI/SMESH_msg_ja.ts +++ b/src/SMESHGUI/SMESH_msg_ja.ts @@ -39,6 +39,10 @@ CGNS_FILES_FILTER CGNS ファイル + + CGNS_EXPORT_ELEMS_BY_TYPE + タイプで要素をグループ化 + GMF_ASCII_FILES_FILTER GMFアスキーファイル @@ -383,6 +387,22 @@ MEN_DEL_GROUP グループとその内容を削除します。 + + MEN_ADD_TO_GROUP + グループに追加 + + + MEN_REMOVE_FROM_GROUP + グループから削除 + + + STB_ADD_TO_GROUP + 選択要素をグループに追加 + + + STB_REMOVE_FROM_GROUP + 選択要素をグループから削除 + MEN_FACE_ORIENTATION フェースの向き @@ -871,6 +891,10 @@ MEN_QUADRATIC_PENTAHEDRON 二次ウェッジ + + MEN_BIQUADRATIC_PENTAHEDRON + 4次五面体 + MEN_QUADRATIC_PYRAMID 四角錐 @@ -1343,6 +1367,10 @@ SMESH_ADD_QUADRATIC_PENTAHEDRON_TITLE 二次くさびを追加します。 + + SMESH_ADD_BIQUADRATIC_PENTAHEDRON_TITLE + 4次五面体の追加 + SMESH_ADD_QUADRATIC_PYRAMID_TITLE 四角錐を追加します。 @@ -2475,10 +2503,18 @@ SMESH_QUADRATIC_PENTAHEDRON 二次ウェッジ + + SMESH_BIQUADRATIC_PENTAHEDRON + 4次五面体 + SMESH_QUADRATIC_PENTAHEDRONS 二次ウェッジ + + SMESH_BIQUADRATIC_PENTAHEDRONS + 4次五面体 + SMESH_QUADRATIC_PYRAMID 四角錐 @@ -3323,6 +3359,10 @@ STB_QUADRATIC_PENTAHEDRON 二次ウェッジ + + STB_BIQUADRATIC_PENTAHEDRON + 4次五面体 + STB_QUADRATIC_PYRAMID 四角錐 @@ -3999,6 +4039,10 @@ TOP_QUADRATIC_PENTAHEDRON 二次ウェッジ + + TOP_BIQUADRATIC_PENTAHEDRON + 4次五面体 + TOP_QUADRATIC_PYRAMID 四角錐 @@ -4827,6 +4871,10 @@ SMESH_ADD_QUADRATIC_PENTAHEDRON 二次くさびを追加します。 + + SMESH_ADD_BIQUADRATIC_PENTAHEDRON + 4次五面体の追加 + SMESH_ADD_QUADRATIC_PYRAMID 二次ピラミッドの追加 @@ -5248,6 +5296,10 @@ SEPARATE_CORNERS_AND_MEDIUM 2次セルのコーナ節点と中間節点をマージできません + + AVOID_MAKING_HOLES + 穴作成の回避 + KEEP_NODES 維持節点 @@ -5943,6 +5995,10 @@ ENTITY_TYPE_24 ボール + + ENTITY_TYPE_25 + ボール + GEOM_TYPE ジオメトリの種類 @@ -6870,6 +6926,14 @@ SMESH_CREATE_GROUP_FROM_GEOM ジオメトリからグループを作成 + + ELEMENTS + 要素 + + + ELEMENTS_TOOLTIP + 0D要素がない + SMESHGUI_MeshOrderDlg @@ -7298,6 +7362,10 @@ ELEM_MODE 要素 + + SHOW_IDS + IDの表示 + BUT_DUMP_MESH 書き出し(&D) diff --git a/src/SMESHUtils/CMakeLists.txt b/src/SMESHUtils/CMakeLists.txt index c84715eed..6750f063c 100644 --- a/src/SMESHUtils/CMakeLists.txt +++ b/src/SMESHUtils/CMakeLists.txt @@ -47,7 +47,7 @@ SET(_link_LIBRARIES ${CAS_TKMesh} ${Boost_LIBRARIES} SMDS -) + ) # --- headers --- @@ -68,7 +68,7 @@ SET(SMESHUtils_HEADERS SMESH_MAT2d.hxx SMESH_ControlPnt.hxx SMESH_Delaunay.hxx -) + ) # --- sources --- @@ -86,6 +86,7 @@ SET(SMESHUtils_SOURCES SMESH_ControlPnt.cxx SMESH_DeMerge.cxx SMESH_Delaunay.cxx + SMESH_FillHole.cxx ) # --- rules --- diff --git a/src/SMESHUtils/SMESH_FillHole.cxx b/src/SMESHUtils/SMESH_FillHole.cxx new file mode 100644 index 000000000..ee22ef944 --- /dev/null +++ b/src/SMESHUtils/SMESH_FillHole.cxx @@ -0,0 +1,517 @@ +// Copyright (C) 2007-2016 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// +// File : SMESH_FillHole.cxx +// Created : Tue Sep 26 15:11:17 2017 +// Author : Edward AGAPOV (eap) +// + +#include "SMESH_MeshAlgos.hxx" + +#include "SMESH_Comment.hxx" + +#include "SMESH_TypeDefs.hxx" +#include "SMDS_Mesh.hxx" + +#include + +#include +#include + +#include + +namespace +{ + bool isSmallAngle( double cos2 ) + { + // cosine of min angle at which adjacent faces are considered overlapping + const double theMinCos2 = 0.996 * 0.996; // ~5 degrees + return ( cos2 > theMinCos2 ); + } + + struct BEdge; + typedef std::multimap< double, BEdge* > TAngleMap; + typedef std::map< const SMDS_MeshElement*, int > TFaceIndMap; + + //-------------------------------------------------------------------------------- + /*! + * \brief Edge of a free border + */ + struct BEdge + { + const SMDS_MeshNode* myNode1; + const SMDS_MeshNode* myNode2; + const SMDS_MeshElement* myFace; // face adjacent to the border + + gp_XYZ myFaceNorm; + gp_XYZ myDir; // myNode1 -> myNode2 + double myDirCoef; // 1. or -1, to make myDir oriented as myNodes in myFace + double myLength; // between nodes + double myAngleWithPrev; // between myDir and -myPrev->myDir + double myMinMaxRatio; // of a possible triangle sides + TAngleMap::iterator myAngleMapPos; + double myOverlapAngle; // angle delta due to overlapping + const SMDS_MeshNode* myNode1Shift; // nodes created to avoid overlapping of faces + const SMDS_MeshNode* myNode2Shift; + + BEdge* myPrev; // neighbors in the border + BEdge* myNext; + + BEdge(): myNode1Shift(0), myNode2Shift(0) {} + void Init( const SMDS_MeshNode* n1, const SMDS_MeshNode* n2, + const SMDS_MeshElement* f=0, + const SMDS_MeshNode* nf1=0, const SMDS_MeshNode* nf2=0 ); + void ComputeAngle( bool reverseAngle = false ); + void ShiftOverlapped( const SMDS_MeshNode* oppNode, + const TFaceIndMap& capFaceWithBordInd, + SMDS_Mesh& mesh, + std::vector& newFaces); + void MakeShiftfFaces( SMDS_Mesh& mesh, + std::vector& newFaces, + const bool isReverse ); + gp_XYZ GetInFaceDir() const { return myFaceNorm ^ myDir * myDirCoef; } + double ShapeFactor() const { return 0.5 * ( 1. - myMinMaxRatio ); } + void InsertSelf(TAngleMap& edgesByAngle, bool isReverseFaces, bool reBind, bool useOverlap ) + { + if ( reBind ) edgesByAngle.erase( myAngleMapPos ); + double key = (( isReverseFaces ? 2 * M_PI - myAngleWithPrev : myAngleWithPrev ) + + myOverlapAngle * useOverlap + + ShapeFactor() ); + myAngleMapPos = edgesByAngle.insert( std::make_pair( key, this )); + } + + // traits used by boost::intrusive::circular_list_algorithms + typedef BEdge node; + typedef BEdge * node_ptr; + typedef const BEdge * const_node_ptr; + static node_ptr get_next(const_node_ptr n) { return n->myNext; } + static void set_next(node_ptr n, node_ptr next) { n->myNext = next; } + static node_ptr get_previous(const_node_ptr n) { return n->myPrev; } + static void set_previous(node_ptr n, node_ptr prev){ n->myPrev = prev; } + }; + + //================================================================================ + /*! + * \brief Initialize a border edge data + */ + //================================================================================ + + void BEdge::Init( const SMDS_MeshNode* n1, + const SMDS_MeshNode* n2, + const SMDS_MeshElement* newFace, // new cap face + const SMDS_MeshNode* nf1, + const SMDS_MeshNode* nf2 ) + { + myNode1 = n1; + myNode2 = n2; + myDir = SMESH_NodeXYZ( n2 ) - SMESH_NodeXYZ( n1 ); + myLength = myDir.Modulus(); + if ( myLength > std::numeric_limits::min() ) + myDir /= myLength; + + myFace = newFace; + if ( !myFace ) + { + TIDSortedElemSet elemSet, avoidSet; + int ind1, ind2; + myFace = SMESH_MeshAlgos::FindFaceInSet( n1, n2, elemSet, avoidSet, &ind1, &ind2 ); + if ( !myFace ) + throw SALOME_Exception( SMESH_Comment("No face sharing nodes #") + << myNode1->GetID() << " and #" << myNode2->GetID()); + avoidSet.insert( myFace ); + if ( SMESH_MeshAlgos::FindFaceInSet( n1, n2, elemSet, avoidSet )) + throw SALOME_Exception( SMESH_Comment("No free border between nodes #") + << myNode1->GetID() << " and #" << myNode2->GetID()); + + myDirCoef = SMESH_MeshAlgos::IsRightOrder( myFace, myNode1, myNode2 ) ? 1. : -1.; + } + + if (! SMESH_MeshAlgos::FaceNormal( myFace, myFaceNorm, /*normalized=*/false )) + { + SMDS_ElemIteratorPtr fIt = myNode1->GetInverseElementIterator( SMDSAbs_Face ); + while ( fIt->more() ) + if ( SMESH_MeshAlgos::FaceNormal( fIt->next(), myFaceNorm, /*normalized=*/false )) + break; + } + + if ( newFace ) + { + myFace = 0; + myDirCoef = SMESH_MeshAlgos::IsRightOrder( newFace, nf1, nf2 ) ? 1. : -1.; + if ( myPrev->myNode2 == n1 ) + myNode1Shift = myPrev->myNode2Shift; + if ( myNext->myNode1 == n2 ) + myNode2Shift = myNext->myNode1Shift; + } + else if ( myDirCoef * myPrev->myDirCoef < 0 ) // different orientation of faces + { + myFaceNorm *= -1; + myDirCoef *= -1; + } + } + + //================================================================================ + /*! + * \brief Compute myAngleWithPrev + */ + //================================================================================ + + void BEdge::ComputeAngle( bool theReverseAngle ) + { + double dot = myDir.Dot( myPrev->myDir.Reversed() ); + if ( dot >= 1 ) myAngleWithPrev = 0; + else if ( dot <= -1 ) myAngleWithPrev = M_PI; + else myAngleWithPrev = acos( dot ); + + bool isObtuse; + gp_XYZ inFaceDirNew = myDir - myPrev->myDir; + gp_XYZ inFaceDir1 = myPrev->GetInFaceDir(); + gp_XYZ inFaceDir2 = this->GetInFaceDir(); + double dot1 = inFaceDirNew * inFaceDir1; + double dot2 = inFaceDirNew * inFaceDir2; + bool isOverlap1 = ( dot1 > 0 ); + bool isOverlap2 = ( dot2 > 0 ); + if ( !myPrev->myFace ) + isObtuse = isOverlap1; + else if ( !myFace ) + isObtuse = isOverlap2; + else + { + double dt1 = myDir.Dot( myPrev->myFaceNorm ); + double dt2 = myPrev->myDir.Dot( myFaceNorm ); + isObtuse = ( dt1 > 0 || dt2 < 0 ); // suppose face normals point outside the border + if ( theReverseAngle ) + isObtuse = !isObtuse; + } + if ( isObtuse ) + { + myAngleWithPrev = 2 * M_PI - myAngleWithPrev; + } + + // if ( ! isObtuse ) + // isObtuse = + // isSmallAngle( 1 - myDir.CrossSquareMagnitude( myPrev->myDir )); // edges co-directed + + myOverlapAngle = 0; + //if ( !isObtuse ) + { + // check if myFace and a triangle built on this and prev edges overlap + if ( isOverlap1 ) + { + double cos2 = dot1 * dot1 / inFaceDirNew.SquareModulus() / inFaceDir1.SquareModulus(); + myOverlapAngle += 1. * M_PI * cos2; + } + if ( isOverlap2 ) + { + double cos2 = dot2 * dot2 / inFaceDirNew.SquareModulus() / inFaceDir2.SquareModulus(); + myOverlapAngle += 1. * M_PI * cos2; + } + } + + { + double len3 = SMESH_NodeXYZ( myPrev->myNode1 ).Distance( myNode2 ); + double minLen = Min( myLength, Min( myPrev->myLength, len3 )); + double maxLen = Max( myLength, Max( myPrev->myLength, len3 )); + myMinMaxRatio = minLen / maxLen; + } + } + + //================================================================================ + /*! + * \brief Check if myFace is overlapped by a triangle formed by myNode's and a + * given node. If so, create shifted nodes to avoid overlapping + */ + //================================================================================ + + void BEdge::ShiftOverlapped( const SMDS_MeshNode* theOppNode, + const TFaceIndMap& theCapFaceWithBordInd, + SMDS_Mesh& theMesh, + std::vector& theNewFaces ) + { + if ( myNode1Shift && myNode2Shift ) + return; + + gp_XYZ inNewFaceDir = SMESH_NodeXYZ( theOppNode ) - SMESH_NodeXYZ( myNode1 ); + double dot = inNewFaceDir.Dot( myFaceNorm ); + double cos2 = dot * dot / myFaceNorm.SquareModulus() / inNewFaceDir.SquareModulus(); + bool isOverlap = ( isSmallAngle( 1 - cos2 ) && GetInFaceDir() * inNewFaceDir > 0 ); + + if ( isOverlap ) + { + gp_XYZ shift = myFaceNorm / myLength / 4; + if ( myFace ) + shift.Reverse(); + if ( !myNode1Shift ) + { + gp_XYZ p = SMESH_NodeXYZ( myNode1 ) + shift; + myNode1Shift = theMesh.AddNode( p.X(), p.Y(), p.Z() ); + myPrev->myNode2Shift = myNode1Shift; + } + if ( !myNode2Shift ) + { + gp_XYZ p = SMESH_NodeXYZ( myNode2 ) + shift; + myNode2Shift = theMesh.AddNode( p.X(), p.Y(), p.Z() ); + myNext->myNode1Shift = myNode2Shift; + } + + // MakeShiftfFaces() for already created cap faces + for ( int is2nd = 0; is2nd < 2; ++is2nd ) + { + const SMDS_MeshNode* ns = is2nd ? myNode2Shift : myNode1Shift; + const SMDS_MeshNode* n = is2nd ? myNode2 : myNode1; + if ( !ns ) continue; + + SMDS_ElemIteratorPtr fIt = n->GetInverseElementIterator( SMDSAbs_Face ); + while ( fIt->more() ) + { + const SMDS_MeshElement* f = fIt->next(); + if ( !f->isMarked() ) continue; + + TFaceIndMap::const_iterator f2i = theCapFaceWithBordInd.find( f ); + if ( f2i == theCapFaceWithBordInd.end() ) + continue; + const SMDS_MeshNode* nf1 = f->GetNode( f2i->second ); + const SMDS_MeshNode* nf2 = f->GetNode(( f2i->second+1 ) % f->NbNodes() ); + if ( nf1 == n || nf2 == n ) + { + BEdge tmpE; + tmpE.myPrev = tmpE.myNext = this; + tmpE.Init( nf1, nf2, f, nf1, nf2 ); + if ( !tmpE.myNode1Shift && !tmpE.myNode2Shift ) + tmpE.Init( nf2, nf1, f, nf2, nf1 ); + tmpE.myFace = f; + tmpE.MakeShiftfFaces( theMesh, theNewFaces, tmpE.myDirCoef < 0 ); + } + std::vector< const SMDS_MeshNode* > nodes( f->begin_nodes(), f->end_nodes() ); + nodes[ f->GetNodeIndex( n ) ] = ns; + theMesh.ChangeElementNodes( f, &nodes[0], nodes.size() ); + } + } + } + } + + //================================================================================ + /*! + * \brief Create a triangle + */ + //================================================================================ + + const SMDS_MeshElement* MakeTria( SMDS_Mesh& mesh, + const SMDS_MeshNode* n1, + const SMDS_MeshNode* n2, + const SMDS_MeshNode* n3, + const bool isReverse ) + { + if ( isReverse ) + return mesh.AddFace( n1, n3, n2 ); + return mesh.AddFace( n1, n2, n3 ); + } + + //================================================================================ + /*! + * \brief Create a quadrangle + */ + //================================================================================ + + // const SMDS_MeshElement* MakeQuad( SMDS_Mesh& mesh, + // const SMDS_MeshNode* n1, + // const SMDS_MeshNode* n2, + // const SMDS_MeshNode* n3, + // const SMDS_MeshNode* n4, + // const bool isReverse ) + // { + // if ( isReverse ) + // return mesh.AddFace( n4, n3, n2, n1 ); + // return mesh.AddFace( n1, n2, n3, n4 ); + // } + + //================================================================================ + /*! + * \brief Create faces on myNode* and myNode*Shift + */ + //================================================================================ + + void BEdge::MakeShiftfFaces(SMDS_Mesh& mesh, + std::vector& newFaces, + const bool isReverse ) + { + if ( !myFace ) + return; + if ( myNode1Shift && myNode2Shift ) + { + newFaces.push_back( MakeTria( mesh, myNode1, myNode2, myNode2Shift, isReverse )); + newFaces.push_back( MakeTria( mesh, myNode1, myNode2Shift, myNode1Shift, isReverse )); + } + else if ( myNode1Shift ) + { + newFaces.push_back( MakeTria( mesh, myNode1, myNode2, myNode1Shift, isReverse )); + } + else if ( myNode2Shift ) + { + newFaces.push_back( MakeTria( mesh, myNode1, myNode2, myNode2Shift, isReverse )); + } + } + +} // namespace + +//================================================================================ +/*! + * \brief Fill with 2D elements a hole defined by a TFreeBorder + */ +//================================================================================ + +void SMESH_MeshAlgos::FillHole(const SMESH_MeshAlgos::TFreeBorder & theFreeBorder, + SMDS_Mesh& theMesh, + std::vector& theNewFaces) +{ + if ( theFreeBorder.size() < 4 || // at least 3 nodes + theFreeBorder[0] != theFreeBorder.back() ) // the hole must be closed + return; + + // prepare data of the border + + ObjectPool< BEdge > edgeAllocator; + boost::intrusive::circular_list_algorithms< BEdge > circularList; + BEdge* edge; + BEdge* edge0 = edgeAllocator.getNew(); + BEdge* edgePrev = edge0; + circularList.init_header( edge0 ); + edge0->Init( theFreeBorder[0], theFreeBorder[1], 0 ); + Bnd_B3d box; + box.Add( SMESH_NodeXYZ( edge0->myNode1 )); + for ( size_t i = 2; i < theFreeBorder.size(); ++i ) + { + edge = edgeAllocator.getNew(); + circularList.link_after( edgePrev, edge ); + edge->Init( theFreeBorder[i-1], theFreeBorder[i] ); + edge->ComputeAngle(); + edgePrev = edge; + box.Add( SMESH_NodeXYZ( edge->myNode1 )); + } + edge0->ComputeAngle(); + + // check if face normals point outside the border + + gp_XYZ hSize = 0.5 * ( box.CornerMax() - box.CornerMin() ); + const double hDelta = 1e-6 * hSize.Modulus(); + hSize -= gp_XYZ( hDelta, hDelta, hDelta ); + if ( hSize.X() < 0 ) hSize.SetX(hDelta); + if ( hSize.Y() < 0 ) hSize.SetY(hDelta); + if ( hSize.Z() < 0 ) hSize.SetZ(hDelta); + box.SetHSize( hSize ); // decrease the box by hDelta + + size_t nbEdges = theFreeBorder.size() - 1; + edge = edge0; + int nbRev = 0, nbFrw = 0; + double angTol = M_PI - ( nbEdges - 2 ) * M_PI / nbEdges, sumDirCoeff = 0; + for ( size_t i = 0; i < nbEdges; ++i, edge = edge->myNext ) + { + if ( box.IsOut( SMESH_NodeXYZ( edge->myNode1 )) && + edge->myOverlapAngle < 0.1 * M_PI ) + { + nbRev += edge->myAngleWithPrev > M_PI + angTol; + nbFrw += edge->myAngleWithPrev < M_PI - angTol; + } + sumDirCoeff += edge->myDirCoef; + + // unmark all adjacent faces, new faces will be marked + SMDS_ElemIteratorPtr fIt = edge->myNode1->GetInverseElementIterator( SMDSAbs_Face ); + while ( fIt->more() ) + fIt->next()->setIsMarked( false ); + } + bool isReverseAngle = ( nbRev > nbFrw ); // true == face normals point inside the border + //std::cout << "nbRev="<< nbRev << ", nbFrw="<< nbFrw<myNext ) + edge->InsertSelf( edgesByAngle, isReverseAngle, /*reBind=*/false, useOverlap ); + + // create triangles to fill the hole + + //compare order of nodes in the edges with their order in faces + bool isReverse = sumDirCoeff > 0.5 * nbEdges; + + // faces filling the hole (cap faces) and indices of border edges in them + TFaceIndMap capFaceWithBordInd; + + theNewFaces.reserve( nbEdges - 2 ); + std::vector< const SMDS_MeshNode* > nodes(3); + while ( edgesByAngle.size() > 2 ) + { + TAngleMap::iterator a2e = edgesByAngle.begin(); + edge = a2e->second; + if ( useOverlap && + a2e->first - edge->ShapeFactor() > M_PI - angTol ) // all new triangles need shift + { + // re-sort the edges w/o overlap consideration + useOverlap = false; + nbEdges = edgesByAngle.size(); + edgesByAngle.clear(); + for ( size_t i = 0; i < nbEdges; ++i, edge = edge->myNext ) + edge->InsertSelf( edgesByAngle, isReverseAngle, /*reBind=*/false, useOverlap ); + a2e = edgesByAngle.begin(); + } + edge = a2e->second; + edgePrev = edge->myPrev; + + // create shift nodes and faces + edgePrev->ShiftOverlapped( edge->myNode2, capFaceWithBordInd, theMesh, theNewFaces ); + edge->ShiftOverlapped( edgePrev->myNode1, capFaceWithBordInd, theMesh, theNewFaces ); + edge ->MakeShiftfFaces( theMesh, theNewFaces, isReverse ); + edgePrev->MakeShiftfFaces( theMesh, theNewFaces, isReverse ); + + // make a cap face + //nodes.resize( 3 ); + nodes[0] = edgePrev->myNode1Shift ? edgePrev->myNode1Shift : edgePrev->myNode1; + nodes[1] = edgePrev->myNode2Shift ? edgePrev->myNode2Shift : edgePrev->myNode2; + nodes[2] = edge->myNode2Shift ? edge->myNode2Shift : edge->myNode2; + theNewFaces.push_back( MakeTria( theMesh, nodes[0], nodes[1], nodes[2], isReverse )); + // std::cout << nodes[1]->GetID() << " " << nodes[0]->GetID() << " " << nodes[2]->GetID() + // << " " << edge->myAngleWithPrev << std::endl; + + // remember a border edge within the new cap face + theNewFaces.back()->setIsMarked( true ); + if ( edgePrev->myFace ) + capFaceWithBordInd.insert( std::make_pair( theNewFaces.back(), isReverse ? 2 : 0 )); + if ( edge->myFace ) + capFaceWithBordInd.insert( std::make_pair( theNewFaces.back(), 1 )); + + // remove edgePrev from the list and update + edgesByAngle.erase( edgePrev->myAngleMapPos ); + circularList.unlink( edgePrev ); // remove edgePrev from the border + + edge->Init( edgePrev->myNode1, edge->myNode2, theNewFaces.back(), nodes[0], nodes[2] ); + edge->ComputeAngle( isReverseAngle ); + edge->InsertSelf( edgesByAngle, /*isReverse=*/false, /*reBind=*/true, useOverlap ); + edge->myNext->ComputeAngle( isReverseAngle ); + edge->myNext->InsertSelf( edgesByAngle, /*isReverse=*/false, /*reBind=*/true, useOverlap ); + // std::cout << "A " << edge->myNode1->GetID() << " " << edge->myAngleWithPrev + // << " " << edge->myNext->myNode1->GetID() << " " << edge->myNext->myAngleWithPrev + // << std::endl; + } + edge = edgesByAngle.begin()->second; + edge-> MakeShiftfFaces( theMesh, theNewFaces, isReverse ); + edge->myNext->MakeShiftfFaces( theMesh, theNewFaces, isReverse ); +} diff --git a/src/SMESHUtils/SMESH_FreeBorders.cxx b/src/SMESHUtils/SMESH_FreeBorders.cxx index ae6efa6db..d09860465 100644 --- a/src/SMESHUtils/SMESH_FreeBorders.cxx +++ b/src/SMESHUtils/SMESH_FreeBorders.cxx @@ -131,8 +131,11 @@ namespace if ( myID < 0 ) { myID = id; - if ( myNext ) - myNext->SetID( id + 1 ); + + for ( BEdge* be = myNext; be && be->myID < 0; be = be->myNext ) + { + be->myID = ++id; + } } } //================================================================================ @@ -821,3 +824,136 @@ void SMESH_MeshAlgos::FindCoincidentFreeBorders(SMDS_Mesh& mesh, } // SMESH_MeshAlgos::FindCoincidentFreeBorders() +//================================================================================ +/* + * Returns all TFreeBorder's. Optionally check if the mesh is manifold + * and if faces are correctly oriented. + */ +//================================================================================ + +void SMESH_MeshAlgos::FindFreeBorders(SMDS_Mesh& theMesh, + TFreeBorderVec & theFoundFreeBordes, + const bool theClosedOnly, + bool* theIsManifold, + bool* theIsGoodOri) +{ + bool isManifold = true; + + // find free links + typedef NCollection_DataMap TLink2FaceMap; + TLink2FaceMap linkMap; + int nbSharedLinks = 0; + SMDS_FaceIteratorPtr faceIt = theMesh.facesIterator(); + while ( faceIt->more() ) + { + const SMDS_MeshElement* face = faceIt->next(); + if ( !face ) continue; + + const SMDS_MeshNode* n0 = face->GetNode( face->NbNodes() - 1 ); + SMDS_NodeIteratorPtr nodeIt = face->interlacedNodesIterator(); + while ( nodeIt->more() ) + { + const SMDS_MeshNode* n1 = nodeIt->next(); + SMESH_TLink link( n0, n1 ); + if ( const SMDS_MeshElement** faceInMap = linkMap.ChangeSeek( link )) + { + if ( *faceInMap ) + { + if ( theIsGoodOri && *theIsGoodOri && !IsRightOrder( *faceInMap, n1, n0 )) + *theIsGoodOri = false; + } + else + { + isManifold = false; + } + nbSharedLinks += bool( *faceInMap ); + *faceInMap = 0; + } + else + { + linkMap.Bind( link, face ); + } + n0 = n1; + } + } + if ( theIsManifold ) + *theIsManifold = isManifold; + + if ( linkMap.Extent() == nbSharedLinks ) + return; + + // form free borders + std::set < BNode > bNodes; + std::vector< BEdge > bEdges( linkMap.Extent() - nbSharedLinks ); + + TLink2FaceMap::Iterator linkIt( linkMap ); + for ( int iEdge = 0; linkIt.More(); linkIt.Next() ) + { + if ( !linkIt.Value() ) continue; + const SMESH_TLink & link = linkIt.Key(); + std::set< BNode >::iterator n1 = bNodes.insert( BNode( link.node1() )).first; + std::set< BNode >::iterator n2 = bNodes.insert( BNode( link.node2() )).first; + bEdges[ iEdge ].Set( &*n1, &*n2, linkIt.Value(), iEdge+1 ); + n1->AddLinked( & bEdges[ iEdge ] ); + n2->AddLinked( & bEdges[ iEdge ] ); + ++iEdge; + } + linkMap.Clear(); + + // assign IDs to borders + std::vector< BEdge* > borders; // 1st of connected (via myPrev and myNext) edges + std::set< BNode >::iterator bn = bNodes.begin(); + for ( ; bn != bNodes.end(); ++bn ) + { + for ( size_t i = 0; i < bn->myLinkedEdges.size(); ++i ) + { + if ( bn->myLinkedEdges[i]->myBorderID < 0 ) + { + BEdge* be = bn->myLinkedEdges[i]; + int borderID = borders.size(); + borders.push_back( be ); + for ( ; be && be->myBorderID < 0; be = be->myNext ) + { + be->myBorderID = borderID; + be->Orient(); + } + bool isClosed = ( be == bn->myLinkedEdges[i] ); + if ( !isClosed && theClosedOnly ) + { + borders.pop_back(); + continue; + } + be = bn->myLinkedEdges[i]->myPrev; + for ( ; be && be->myBorderID < 0; be = be->myPrev ) + { + be->myBorderID = borderID; + be->Orient(); + } + if ( !isClosed ) + while ( borders.back()->myPrev ) + borders.back() = borders.back()->myPrev; + } + } + } + theFoundFreeBordes.resize( borders.size() ); + for ( size_t i = 0; i < borders.size(); ++i ) + { + TFreeBorder & bordNodes = theFoundFreeBordes[ i ]; + BEdge* be = borders[i]; + + size_t cnt = 1; + for ( be = be->myNext; be && be != borders[i]; be = be->myNext ) + ++cnt; + bordNodes.resize( cnt + 1 ); + + BEdge* beLast; + for ( be = borders[i], cnt = 0; + be && cnt < bordNodes.size()-1; + be = be->myNext, ++cnt ) + { + bordNodes[ cnt ] = be->myBNode1->Node(); + beLast = be; + } + bordNodes.back() = beLast->myBNode2->Node(); + } +} diff --git a/src/SMESHUtils/SMESH_MeshAlgos.cxx b/src/SMESHUtils/SMESH_MeshAlgos.cxx index 8464e245f..dbf355e11 100644 --- a/src/SMESHUtils/SMESH_MeshAlgos.cxx +++ b/src/SMESHUtils/SMESH_MeshAlgos.cxx @@ -35,6 +35,8 @@ #include "SMDS_VolumeTool.hxx" #include "SMESH_OctreeNode.hxx" +#include + #include #include #include @@ -228,12 +230,12 @@ namespace // Utils used in SMESH_ElementSearcherImpl::FindElementsByPoint() SMDSAbs_ElementType elemType, SMDS_ElemIteratorPtr theElemIt = SMDS_ElemIteratorPtr(), double tolerance = NodeRadius ); - void prepare(); // !!!call it before calling the following methods!!! void getElementsNearPoint( const gp_Pnt& point, vector& foundElems ); void getElementsNearLine ( const gp_Ax1& line, vector& foundElems); void getElementsInSphere ( const gp_XYZ& center, const double radius, vector& foundElems); + ElementBndBoxTree* getLeafAtPoint( const gp_XYZ& point ); protected: ElementBndBoxTree() {} @@ -337,19 +339,6 @@ namespace // Utils used in SMESH_ElementSearcherImpl::FindElementsByPoint() } } - //================================================================================ - /*! - * \brief Un-mark all elements - */ - //================================================================================ - - void ElementBndBoxTree::prepare() - { - // TElementBoxPool& elBoPool = getElementBoxPool(); - // for ( size_t i = 0; i < elBoPool.nbElements(); ++i ) - // const_cast< ElementBox* >( elBoPool[ i ])->_isMarked = false; - } - //================================================================================ /*! * \brief Return elements which can include the point @@ -471,6 +460,30 @@ namespace // Utils used in SMESH_ElementSearcherImpl::FindElementsByPoint() } } + //================================================================================ + /*! + * \brief Return a leaf including a point + */ + //================================================================================ + + ElementBndBoxTree* ElementBndBoxTree::getLeafAtPoint( const gp_XYZ& point ) + { + if ( getBox()->IsOut( point )) + return 0; + + if ( isLeaf() ) + { + return this; + } + else + { + for (int i = 0; i < 8; i++) + if ( ElementBndBoxTree* l = ((ElementBndBoxTree*) myChildren[i])->getLeafAtPoint( point )) + return l; + } + return 0; + } + //================================================================================ /*! * \brief Construct the element box @@ -539,13 +552,16 @@ struct SMESH_ElementSearcherImpl: public SMESH_ElementSearcher virtual const SMDS_MeshElement* FindClosestTo( const gp_Pnt& point, SMDSAbs_ElementType type ); - void GetElementsNearLine( const gp_Ax1& line, - SMDSAbs_ElementType type, - vector< const SMDS_MeshElement* >& foundElems); - void GetElementsInSphere( const gp_XYZ& center, - const double radius, - SMDSAbs_ElementType type, - vector< const SMDS_MeshElement* >& foundElems); + virtual void GetElementsNearLine( const gp_Ax1& line, + SMDSAbs_ElementType type, + vector< const SMDS_MeshElement* >& foundElems); + virtual void GetElementsInSphere( const gp_XYZ& center, + const double radius, + SMDSAbs_ElementType type, + vector< const SMDS_MeshElement* >& foundElems); + virtual gp_XYZ Project(const gp_Pnt& point, + SMDSAbs_ElementType type, + const SMDS_MeshElement** closestElem); double getTolerance(); bool getIntersParamOnLine(const gp_Lin& line, const SMDS_MeshElement* face, const double tolerance, double & param); @@ -834,10 +850,6 @@ FindElementsByPoint(const gp_Pnt& point, { _ebbTree[_elementType] = new ElementBndBoxTree( *_mesh, type, _meshPartIt, tolerance ); } - else - { - _ebbTree[ type ]->prepare(); - } vector< const SMDS_MeshElement* > suspectElems; _ebbTree[ type ]->getElementsNearPoint( point, suspectElems ); vector< const SMDS_MeshElement* >::iterator elem = suspectElems.begin(); @@ -863,13 +875,13 @@ SMESH_ElementSearcherImpl::FindClosestTo( const gp_Pnt& point, const SMDS_MeshElement* closestElem = 0; _elementType = type; - if ( type == SMDSAbs_Face || type == SMDSAbs_Volume ) + if ( type == SMDSAbs_Face || + type == SMDSAbs_Volume || + type == SMDSAbs_Edge ) { ElementBndBoxTree*& ebbTree = _ebbTree[ type ]; if ( !ebbTree ) ebbTree = new ElementBndBoxTree( *_mesh, type, _meshPartIt ); - else - ebbTree->prepare(); vector suspectElems; ebbTree->getElementsNearPoint( point, suspectElems ); @@ -885,7 +897,6 @@ SMESH_ElementSearcherImpl::FindClosestTo( const gp_Pnt& point, radius = ebbTree->maxSize() / pow( 2., getTreeHeight()) / 2; while ( suspectElems.empty() ) { - ebbTree->prepare(); ebbTree->getElementsInSphere( point.XYZ(), radius, suspectElems ); radius *= 1.1; } @@ -956,8 +967,6 @@ TopAbs_State SMESH_ElementSearcherImpl::GetPointState(const gp_Pnt& point) ElementBndBoxTree*& ebbTree = _ebbTree[ SMDSAbs_Face ]; if ( !ebbTree ) ebbTree = new ElementBndBoxTree( *_mesh, _elementType, _meshPartIt ); - else - ebbTree->prepare(); // Algo: analyse transition of a line starting at the point through mesh boundary; // try three lines parallel to axis of the coordinate system and perform rough @@ -974,7 +983,6 @@ TopAbs_State SMESH_ElementSearcherImpl::GetPointState(const gp_Pnt& point) gp_Lin line ( lineAxis ); vector suspectFaces; // faces possibly intersecting the line - if ( axis > 0 ) ebbTree->prepare(); ebbTree->getElementsNearLine( lineAxis, suspectFaces ); // Intersect faces with the line @@ -1187,8 +1195,6 @@ void SMESH_ElementSearcherImpl::GetElementsNearLine( const gp_Ax1& ElementBndBoxTree*& ebbTree = _ebbTree[ type ]; if ( !ebbTree ) ebbTree = new ElementBndBoxTree( *_mesh, _elementType, _meshPartIt ); - else - ebbTree->prepare(); ebbTree->getElementsNearLine( line, foundElems ); } @@ -1208,12 +1214,59 @@ void SMESH_ElementSearcherImpl::GetElementsInSphere( const gp_XYZ& ElementBndBoxTree*& ebbTree = _ebbTree[ type ]; if ( !ebbTree ) ebbTree = new ElementBndBoxTree( *_mesh, _elementType, _meshPartIt ); - else - ebbTree->prepare(); ebbTree->getElementsInSphere( center, radius, foundElems ); } +//======================================================================= +/* + * \brief Return a projection of a given point to a mesh. + * Optionally return the closest element + */ +//======================================================================= + +gp_XYZ SMESH_ElementSearcherImpl::Project(const gp_Pnt& point, + SMDSAbs_ElementType type, + const SMDS_MeshElement** closestElem) +{ + _elementType = type; + if ( _mesh->GetMeshInfo().NbElements( _elementType ) == 0 ) + throw SALOME_Exception( LOCALIZED( "No elements of given type in the mesh" )); + + ElementBndBoxTree*& ebbTree = _ebbTree[ _elementType ]; + if ( !ebbTree ) + ebbTree = new ElementBndBoxTree( *_mesh, _elementType ); + + gp_XYZ p = point.XYZ(); + ElementBndBoxTree* ebbLeaf = ebbTree->getLeafAtPoint( p ); + const Bnd_B3d* box = ebbLeaf->getBox(); + double radius = ( box->CornerMax() - box->CornerMin() ).Modulus(); + + vector< const SMDS_MeshElement* > elems; + ebbTree->getElementsInSphere( p, radius, elems ); + while ( elems.empty() ) + { + radius *= 1.5; + ebbTree->getElementsInSphere( p, radius, elems ); + } + gp_XYZ proj, bestProj; + const SMDS_MeshElement* elem = 0; + double minDist = 2 * radius; + for ( size_t i = 0; i < elems.size(); ++i ) + { + double d = SMESH_MeshAlgos::GetDistance( elems[i], p, &proj ); + if ( d < minDist ) + { + bestProj = proj; + elem = elems[i]; + minDist = d; + } + } + if ( closestElem ) *closestElem = elem; + + return bestProj; +} + //======================================================================= /*! * \brief Return true if the point is IN or ON of the element @@ -1461,17 +1514,19 @@ namespace //======================================================================= double SMESH_MeshAlgos::GetDistance( const SMDS_MeshElement* elem, - const gp_Pnt& point ) + const gp_Pnt& point, + gp_XYZ* closestPnt ) { switch ( elem->GetType() ) { case SMDSAbs_Volume: - return GetDistance( dynamic_cast( elem ), point); + return GetDistance( dynamic_cast( elem ), point, closestPnt ); case SMDSAbs_Face: - return GetDistance( dynamic_cast( elem ), point); + return GetDistance( dynamic_cast( elem ), point, closestPnt ); case SMDSAbs_Edge: - return GetDistance( dynamic_cast( elem ), point); + return GetDistance( dynamic_cast( elem ), point, closestPnt ); case SMDSAbs_Node: + if ( closestPnt ) *closestPnt = SMESH_TNodeXYZ( elem ); return point.Distance( SMESH_TNodeXYZ( elem )); default:; } @@ -1487,9 +1542,10 @@ double SMESH_MeshAlgos::GetDistance( const SMDS_MeshElement* elem, //======================================================================= double SMESH_MeshAlgos::GetDistance( const SMDS_MeshFace* face, - const gp_Pnt& point ) + const gp_Pnt& point, + gp_XYZ* closestPnt ) { - double badDistance = -1; + const double badDistance = -1; if ( !face ) return badDistance; // coordinates of nodes (medium nodes, if any, ignored) @@ -1533,7 +1589,7 @@ double SMESH_MeshAlgos::GetDistance( const SMDS_MeshFace* face, trsf.Transforms( tmpPnt ); gp_XY point2D( tmpPnt.X(), tmpPnt.Z() ); - // loop on segments of the face to analyze point position ralative to the face + // loop on edges of the face to analyze point position ralative to the face set< PointPos > pntPosSet; for ( size_t i = 1; i < xy.size(); ++i ) { @@ -1543,31 +1599,40 @@ double SMESH_MeshAlgos::GetDistance( const SMDS_MeshFace* face, // compute distance PointPos pos = *pntPosSet.begin(); - // cout << "Face " << face->GetID() << " DIST: "; switch ( pos._name ) { - case POS_LEFT: { - // point is most close to a segment - gp_Vec p0p1( point, xyz[ pos._index ] ); - gp_Vec p1p2( xyz[ pos._index ], xyz[ pos._index+1 ]); // segment vector - p1p2.Normalize(); - double projDist = p0p1 * p1p2; // distance projected to the segment - gp_Vec projVec = p1p2 * projDist; - gp_Vec distVec = p0p1 - projVec; - // cout << distVec.Magnitude() << ", SEG " << face->GetNode(pos._index)->GetID() - // << " - " << face->GetNodeWrap(pos._index+1)->GetID() << endl; - return distVec.Magnitude(); + case POS_LEFT: + { + // point is most close to an edge + gp_Vec edge( xyz[ pos._index ], xyz[ pos._index+1 ]); + gp_Vec n1p ( xyz[ pos._index ], point ); + double u = ( edge * n1p ) / edge.SquareMagnitude(); // param [0,1] on the edge + // projection of the point on the edge + gp_XYZ proj = ( 1. - u ) * xyz[ pos._index ] + u * xyz[ pos._index+1 ]; + if ( closestPnt ) *closestPnt = proj; + return point.Distance( proj ); } - case POS_RIGHT: { + case POS_RIGHT: + { // point is inside the face - double distToFacePlane = tmpPnt.Y(); - // cout << distToFacePlane << ", INSIDE " << endl; - return Abs( distToFacePlane ); + double distToFacePlane = Abs( tmpPnt.Y() ); + if ( closestPnt ) + { + if ( distToFacePlane < std::numeric_limits::min() ) { + *closestPnt = point.XYZ(); + } + else { + tmpPnt.SetY( 0 ); + trsf.Inverted().Transforms( tmpPnt ); + *closestPnt = tmpPnt; + } + } + return distToFacePlane; } - case POS_VERTEX: { + case POS_VERTEX: + { // point is most close to a node gp_Vec distVec( point, xyz[ pos._index ]); - // cout << distVec.Magnitude() << " VERTEX " << face->GetNode(pos._index)->GetID() << endl; return distVec.Magnitude(); } default:; @@ -1581,7 +1646,9 @@ double SMESH_MeshAlgos::GetDistance( const SMDS_MeshFace* face, */ //======================================================================= -double SMESH_MeshAlgos::GetDistance( const SMDS_MeshEdge* seg, const gp_Pnt& point ) +double SMESH_MeshAlgos::GetDistance( const SMDS_MeshEdge* seg, + const gp_Pnt& point, + gp_XYZ* closestPnt ) { double dist = Precision::Infinite(); if ( !seg ) return dist; @@ -1597,16 +1664,25 @@ double SMESH_MeshAlgos::GetDistance( const SMDS_MeshEdge* seg, const gp_Pnt& poi { gp_Vec edge( xyz[i-1], xyz[i] ); gp_Vec n1p ( xyz[i-1], point ); - double u = ( edge * n1p ) / edge.SquareMagnitude(); // param [0,1] on the edge + double d, u = ( edge * n1p ) / edge.SquareMagnitude(); // param [0,1] on the edge if ( u <= 0. ) { - dist = Min( dist, n1p.SquareMagnitude() ); + if (( d = n1p.SquareMagnitude() ) < dist ) { + dist = d; + if ( closestPnt ) *closestPnt = xyz[i-1]; + } } else if ( u >= 1. ) { - dist = Min( dist, point.SquareDistance( xyz[i] )); + if (( d = point.SquareDistance( xyz[i] )) < dist ) { + dist = d; + if ( closestPnt ) *closestPnt = xyz[i]; + } } else { - gp_XYZ proj = ( 1. - u ) * xyz[i-1] + u * xyz[i]; // projection of the point on the edge - dist = Min( dist, point.SquareDistance( proj )); + gp_XYZ proj = xyz[i-1] + u * edge.XYZ(); // projection of the point on the edge + if (( d = point.SquareDistance( proj )) < dist ) { + dist = d; + if ( closestPnt ) *closestPnt = proj; + } } } return Sqrt( dist ); @@ -1620,7 +1696,9 @@ double SMESH_MeshAlgos::GetDistance( const SMDS_MeshEdge* seg, const gp_Pnt& poi */ //======================================================================= -double SMESH_MeshAlgos::GetDistance( const SMDS_MeshVolume* volume, const gp_Pnt& point ) +double SMESH_MeshAlgos::GetDistance( const SMDS_MeshVolume* volume, + const gp_Pnt& point, + gp_XYZ* closestPnt ) { SMDS_VolumeTool vTool( volume ); vTool.SetExternalNormal(); @@ -1628,6 +1706,8 @@ double SMESH_MeshAlgos::GetDistance( const SMDS_MeshVolume* volume, const gp_Pnt double n[3], bc[3]; double minDist = 1e100, dist; + gp_XYZ closeP = point.XYZ(); + bool isOut = false; for ( int iF = 0; iF < vTool.NbFaces(); ++iF ) { // skip a facet with normal not "looking at" the point @@ -1644,23 +1724,34 @@ double SMESH_MeshAlgos::GetDistance( const SMDS_MeshVolume* volume, const gp_Pnt case 3: { SMDS_FaceOfNodes tmpFace( nodes[0], nodes[ 1*iQ ], nodes[ 2*iQ ] ); - dist = GetDistance( &tmpFace, point ); + dist = GetDistance( &tmpFace, point, closestPnt ); break; } case 4: { SMDS_FaceOfNodes tmpFace( nodes[0], nodes[ 1*iQ ], nodes[ 2*iQ ], nodes[ 3*iQ ]); - dist = GetDistance( &tmpFace, point ); + dist = GetDistance( &tmpFace, point, closestPnt ); break; } default: vector nvec( nodes, nodes + vTool.NbFaceNodes( iF )); SMDS_PolygonalFaceOfNodes tmpFace( nvec ); - dist = GetDistance( &tmpFace, point ); + dist = GetDistance( &tmpFace, point, closestPnt ); + } + if ( dist < minDist ) + { + minDist = dist; + isOut = true; + if ( closestPnt ) closeP = *closestPnt; } - minDist = Min( minDist, dist ); } - return minDist; + if ( isOut ) + { + if ( closestPnt ) *closestPnt = closeP; + return minDist; + } + + return 0; // point is inside the volume } //================================================================================ @@ -1804,6 +1895,34 @@ vector< const SMDS_MeshNode*> SMESH_MeshAlgos::GetCommonNodes(const SMDS_MeshEle common.push_back( e1->GetNode( i )); return common; } +//================================================================================ +/*! + * \brief Return true if node1 encounters first in the face and node2, after + */ +//================================================================================ + +bool SMESH_MeshAlgos::IsRightOrder( const SMDS_MeshElement* face, + const SMDS_MeshNode* node0, + const SMDS_MeshNode* node1 ) +{ + int i0 = face->GetNodeIndex( node0 ); + int i1 = face->GetNodeIndex( node1 ); + if ( face->IsQuadratic() ) + { + if ( face->IsMediumNode( node0 )) + { + i0 -= ( face->NbNodes()/2 - 1 ); + i1 *= 2; + } + else + { + i1 -= ( face->NbNodes()/2 - 1 ); + i0 *= 2; + } + } + int diff = i1 - i0; + return ( diff == 1 ) || ( diff == -face->NbNodes()+1 ); +} //======================================================================= /*! diff --git a/src/SMESHUtils/SMESH_MeshAlgos.hxx b/src/SMESHUtils/SMESH_MeshAlgos.hxx index 1114bfe02..10af7a636 100644 --- a/src/SMESHUtils/SMESH_MeshAlgos.hxx +++ b/src/SMESHUtils/SMESH_MeshAlgos.hxx @@ -100,6 +100,15 @@ struct SMESHUtils_EXPORT SMESH_ElementSearcher * \brief Find out if the given point is out of closed 2D mesh. */ virtual TopAbs_State GetPointState(const gp_Pnt& point) = 0; + + /*! + * \brief Return a projection of a given point to a 2D mesh. + * Optionally return the closest face + */ + virtual gp_XYZ Project(const gp_Pnt& point, + SMDSAbs_ElementType type, + const SMDS_MeshElement** closestFace= 0) = 0; + virtual ~SMESH_ElementSearcher(); }; @@ -112,16 +121,16 @@ namespace SMESH_MeshAlgos bool IsOut( const SMDS_MeshElement* element, const gp_Pnt& point, double tol ); SMESHUtils_EXPORT - double GetDistance( const SMDS_MeshElement* elem, const gp_Pnt& point ); + double GetDistance( const SMDS_MeshElement* elem, const gp_Pnt& point, gp_XYZ* closestPnt = 0 ); SMESHUtils_EXPORT - double GetDistance( const SMDS_MeshEdge* edge, const gp_Pnt& point ); + double GetDistance( const SMDS_MeshEdge* edge, const gp_Pnt& point, gp_XYZ* closestPnt = 0 ); SMESHUtils_EXPORT - double GetDistance( const SMDS_MeshFace* face, const gp_Pnt& point ); + double GetDistance( const SMDS_MeshFace* face, const gp_Pnt& point, gp_XYZ* closestPnt = 0 ); SMESHUtils_EXPORT - double GetDistance( const SMDS_MeshVolume* volume, const gp_Pnt& point ); + double GetDistance( const SMDS_MeshVolume* volume, const gp_Pnt& point, gp_XYZ* closestPnt = 0 ); SMESHUtils_EXPORT void GetBarycentricCoords( const gp_XY& point, @@ -153,6 +162,14 @@ namespace SMESH_MeshAlgos SMESHUtils_EXPORT std::vector< const SMDS_MeshNode*> GetCommonNodes(const SMDS_MeshElement* e1, const SMDS_MeshElement* e2); + /*! + * \brief Return true if node1 encounters first in the face and node2, after. + * The nodes are supposed to be neighbor nodes in the face. + */ + SMESHUtils_EXPORT + bool IsRightOrder( const SMDS_MeshElement* face, + const SMDS_MeshNode* node0, + const SMDS_MeshNode* node1 ); /*! * \brief Return SMESH_NodeSearcher. The caller is responsible for deleteing it @@ -204,7 +221,28 @@ namespace SMESH_MeshAlgos void FindCoincidentFreeBorders(SMDS_Mesh& mesh, double tolerance, CoincidentFreeBorders & foundFreeBordes); - + /*! + * Returns all or only closed TFreeBorder's. + * Optionally check if the mesh is manifold and if faces are correctly oriented. + * + * (Implemented in ./SMESH_FreeBorders.cxx) + */ + SMESHUtils_EXPORT + void FindFreeBorders(SMDS_Mesh& mesh, + TFreeBorderVec & foundFreeBordes, + const bool closedOnly, + bool* isManifold = 0, + bool* isGoodOri = 0); + /*! + * Fill a hole defined by a TFreeBorder with 2D elements. + * + * (Implemented in ./SMESH_FillHole.cxx) + */ + SMESHUtils_EXPORT + void FillHole(const TFreeBorder & freeBorder, + SMDS_Mesh& mesh, + std::vector& newFaces); + /*! * \brief Find nodes whose merge makes the element invalid diff --git a/src/SMESHUtils/SMESH_TryCatch.cxx b/src/SMESHUtils/SMESH_TryCatch.cxx index 1f987213a..71e587caa 100644 --- a/src/SMESHUtils/SMESH_TryCatch.cxx +++ b/src/SMESHUtils/SMESH_TryCatch.cxx @@ -32,6 +32,12 @@ void SMESH::doNothing(const char* txt) { MESSAGE( txt << " " << __FILE__ << ": " << __LINE__ ); } + +const char* SMESH::returnError(const char* txt) +{ + return txt; +} + // ------------------------------------------------------------------ #include "SMESH_ComputeError.hxx" diff --git a/src/SMESHUtils/SMESH_TryCatch.hxx b/src/SMESHUtils/SMESH_TryCatch.hxx index ccdf3b1da..9e5ffd755 100644 --- a/src/SMESHUtils/SMESH_TryCatch.hxx +++ b/src/SMESHUtils/SMESH_TryCatch.hxx @@ -33,7 +33,6 @@ #include #include #include -#include #include // IMPORTANT: include this file _after_ OCC ones, else OCC_CATCH_SIGNALS can be undefined! @@ -42,7 +41,11 @@ #define OCC_CATCH_SIGNALS #endif -// Define macros to catch and convert some of possible exceptions into text or SALOME_Exception +// Define macros to catch and convert some of possible exceptions into text or SALOME_Exception. +// WARNING: SALOME::SALOME_Exception (CORBA exception) is not treated here; to care about it add +// #define SMY_OWN_CATCH catch ( SALOME::SALOME_Exception & e ) { do_something(e); } +// before #include + //------------------------------------------------------------------------------------- #define SMESH_TRY \ @@ -104,6 +107,7 @@ namespace SMESH { SMESHUtils_EXPORT void throwSalomeEx(const char* txt); SMESHUtils_EXPORT void doNothing(const char* txt); + SMESHUtils_EXPORT const char* returnError(const char* txt); } #endif diff --git a/src/SMESHUtils/SMESH_TypeDefs.hxx b/src/SMESHUtils/SMESH_TypeDefs.hxx index c9be990f6..4c2dddab0 100644 --- a/src/SMESHUtils/SMESH_TypeDefs.hxx +++ b/src/SMESHUtils/SMESH_TypeDefs.hxx @@ -149,7 +149,6 @@ struct SMESH_OrientedLink: public SMESH_TLink struct SMESH_TNodeXYZ : public gp_XYZ { const SMDS_MeshNode* _node; - double _xyz[3]; SMESH_TNodeXYZ( const SMDS_MeshElement* e=0):gp_XYZ(0,0,0),_node(0) { Set(e); @@ -159,15 +158,14 @@ struct SMESH_TNodeXYZ : public gp_XYZ if (e) { assert( e->GetType() == SMDSAbs_Node ); _node = static_cast(e); - _node->GetXYZ(_xyz); // - thread safe getting coords - SetCoord( _xyz[0], _xyz[1], _xyz[2] ); + _node->GetXYZ( ChangeData() ); // - thread safe getting coords return true; } return false; } double Distance(const SMDS_MeshNode* n) const { return (SMESH_TNodeXYZ( n )-*this).Modulus(); } double SquareDistance(const SMDS_MeshNode* n) const { return (SMESH_TNodeXYZ( n )-*this).SquareModulus(); } - bool operator==(const SMESH_TNodeXYZ& other) const { return _node == other._node; } + bool operator==(const SMESH_TNodeXYZ& other) const { return _node == other._node; } }; typedef SMESH_TNodeXYZ SMESH_NodeXYZ; diff --git a/src/SMESH_I/SMESH_2smeshpy.cxx b/src/SMESH_I/SMESH_2smeshpy.cxx index 8cd274b8d..cbfe62c19 100644 --- a/src/SMESH_I/SMESH_2smeshpy.cxx +++ b/src/SMESH_I/SMESH_2smeshpy.cxx @@ -50,29 +50,29 @@ #include #endif -OCCT_IMPLEMENT_STANDARD_RTTIEXT(_pyObject ,Standard_Transient); -OCCT_IMPLEMENT_STANDARD_RTTIEXT(_pyCommand ,Standard_Transient); -OCCT_IMPLEMENT_STANDARD_RTTIEXT(_pyHypothesisReader,Standard_Transient); -OCCT_IMPLEMENT_STANDARD_RTTIEXT(_pyGen ,_pyObject); -OCCT_IMPLEMENT_STANDARD_RTTIEXT(_pyMesh ,_pyObject); -OCCT_IMPLEMENT_STANDARD_RTTIEXT(_pySubMesh ,_pyObject); -OCCT_IMPLEMENT_STANDARD_RTTIEXT(_pyMeshEditor ,_pyObject); -OCCT_IMPLEMENT_STANDARD_RTTIEXT(_pyHypothesis ,_pyObject); -OCCT_IMPLEMENT_STANDARD_RTTIEXT(_pySelfEraser ,_pyObject); -OCCT_IMPLEMENT_STANDARD_RTTIEXT(_pyGroup ,_pyObject); -OCCT_IMPLEMENT_STANDARD_RTTIEXT(_pyFilter ,_pyObject); -OCCT_IMPLEMENT_STANDARD_RTTIEXT(_pyAlgorithm ,_pyHypothesis); -OCCT_IMPLEMENT_STANDARD_RTTIEXT(_pyComplexParamHypo,_pyHypothesis); -OCCT_IMPLEMENT_STANDARD_RTTIEXT(_pyNumberOfSegmentsHyp,_pyHypothesis); -OCCT_IMPLEMENT_STANDARD_RTTIEXT(_pyLayerDistributionHypo,_pyHypothesis); -OCCT_IMPLEMENT_STANDARD_RTTIEXT(_pySegmentLengthAroundVertexHyp,_pyHypothesis); +IMPLEMENT_STANDARD_RTTIEXT(_pyObject ,Standard_Transient); +IMPLEMENT_STANDARD_RTTIEXT(_pyCommand ,Standard_Transient); +IMPLEMENT_STANDARD_RTTIEXT(_pyHypothesisReader,Standard_Transient); +IMPLEMENT_STANDARD_RTTIEXT(_pyGen ,_pyObject); +IMPLEMENT_STANDARD_RTTIEXT(_pyMesh ,_pyObject); +IMPLEMENT_STANDARD_RTTIEXT(_pySubMesh ,_pyObject); +IMPLEMENT_STANDARD_RTTIEXT(_pyMeshEditor ,_pyObject); +IMPLEMENT_STANDARD_RTTIEXT(_pyHypothesis ,_pyObject); +IMPLEMENT_STANDARD_RTTIEXT(_pySelfEraser ,_pyObject); +IMPLEMENT_STANDARD_RTTIEXT(_pyGroup ,_pyObject); +IMPLEMENT_STANDARD_RTTIEXT(_pyFilter ,_pyObject); +IMPLEMENT_STANDARD_RTTIEXT(_pyAlgorithm ,_pyHypothesis); +IMPLEMENT_STANDARD_RTTIEXT(_pyComplexParamHypo,_pyHypothesis); +IMPLEMENT_STANDARD_RTTIEXT(_pyNumberOfSegmentsHyp,_pyHypothesis); +IMPLEMENT_STANDARD_RTTIEXT(_pyLayerDistributionHypo,_pyHypothesis); +IMPLEMENT_STANDARD_RTTIEXT(_pySegmentLengthAroundVertexHyp,_pyHypothesis); using namespace std; using SMESH::TPythonDump; /*! * \brief Container of commands into which the initial script is split. - * It also contains data coresponding to SMESH_Gen contents + * It also contains data corresponding to SMESH_Gen contents */ static Handle(_pyGen) theGen; @@ -294,6 +294,8 @@ namespace { // - FT_BelongToMeshGroup = 22 // v 8.1.0: FT_Undefined == 48, new items: // - FT_NodeConnectivityNumber= 22 + // v 8.5.0: FT_Undefined == 49, new items: + // - FT_Deflection2D = 22 // // It's necessary to continue recording this history and to fill // undef2newItems (see below) accordingly. @@ -316,6 +318,7 @@ namespace { undef2newItems[ 46 ].push_back( 39 ); undef2newItems[ 47 ].push_back( 22 ); undef2newItems[ 48 ].push_back( 22 ); + undef2newItems[ 49 ].push_back( 22 ); ASSERT( undef2newItems.rbegin()->first == SMESH::FT_Undefined ); } @@ -610,7 +613,7 @@ const char* _pyGen::AccessorMethod() const //================================================================================ /*! * \brief Convert a command using a specific converter - * \param theCommand - the command to convert + * \param theCommand - the command to convert */ //================================================================================ @@ -864,8 +867,8 @@ Handle(_pyCommand) _pyGen::AddCommand( const TCollection_AsciiString& theCommand aCommand->GetString() += tmpCmd.GetString(); } // IMP issue 0021014 - // set GetCriterion(elementType,CritType,Compare,Treshold,UnaryOp,BinaryOp,Tolerance) - // 1 2 3 4 5 6 7 + // set GetCriterion(elementType,CritType,Compare,Threshold,UnaryOp,BinaryOp,Tolerance) + // 1 2 3 4 5 6 7 // instead of "SMESH.Filter.Criterion( // Type,Compare,Threshold,ThresholdStr,ThresholdID,UnaryOp,BinaryOp,Tolerance,TypeOfElement,Precision) // 1 2 3 4 5 6 7 8 9 10 @@ -929,7 +932,7 @@ Handle(_pyCommand) _pyGen::AddCommand( const TCollection_AsciiString& theCommand "Entity_Polygon", "Entity_Quad_Polygon", "Entity_Tetra", "Entity_Quad_Tetra", "Entity_Pyramid", "Entity_Quad_Pyramid", "Entity_Hexa", "Entity_Quad_Hexa", "Entity_TriQuad_Hexa", - "Entity_Penta", "Entity_Quad_Penta", "Entity_Hexagonal_Prism", + "Entity_Penta", "Entity_Quad_Penta", "Entity_BiQuad_Penta", "Entity_Hexagonal_Prism", "Entity_Polyhedra", "Entity_Quad_Polyhedra", "Entity_Ball" }; if ( -1 < iGeom && iGeom < nbTypes ) Threshold = SMESH + types[ iGeom ]; @@ -973,7 +976,7 @@ Handle(_pyCommand) _pyGen::AddCommand( const TCollection_AsciiString& theCommand //================================================================================ /*! * \brief Convert the command or remember it for later conversion - * \param theCommand - The python command calling a method of SMESH_Gen + * \param theCommand - The python command calling a method of SMESH_Gen */ //================================================================================ @@ -1282,8 +1285,8 @@ void _pyGen::Free() //================================================================================ /*! * \brief Add access method to mesh that is an argument - * \param theCmd - command to add access method - * \retval bool - true if added + * \param theCmd - command to add access method + * \retval bool - true if added */ //================================================================================ @@ -1301,8 +1304,8 @@ bool _pyGen::AddMeshAccessorMethod( Handle(_pyCommand) theCmd ) const //================================================================================ /*! * \brief Add access method to algo that is an object or an argument - * \param theCmd - command to add access method - * \retval bool - true if added + * \param theCmd - command to add access method + * \retval bool - true if added */ //================================================================================ @@ -1323,8 +1326,8 @@ bool _pyGen::AddAlgoAccessorMethod( Handle(_pyCommand) theCmd ) const //================================================================================ /*! * \brief Find hypothesis by ID (entry) - * \param theHypID - The hypothesis ID - * \retval Handle(_pyHypothesis) - The found hypothesis + * \param theHypID - The hypothesis ID + * \retval Handle(_pyHypothesis) - The found hypothesis */ //================================================================================ @@ -1341,10 +1344,10 @@ Handle(_pyHypothesis) _pyGen::FindHyp( const _pyID& theHypID ) //================================================================================ /*! * \brief Find algorithm able to create a hypothesis - * \param theGeom - The shape ID the algorithm was created on - * \param theMesh - The mesh ID that created the algorithm - * \param theHypothesis - The hypothesis the algorithm should be able to create - * \retval Handle(_pyHypothesis) - The found algo + * \param theGeom - The shape ID the algorithm was created on + * \param theMesh - The mesh ID that created the algorithm + * \param theHypothesis - The hypothesis the algorithm should be able to create + * \retval Handle(_pyHypothesis) - The found algo */ //================================================================================ @@ -1365,8 +1368,8 @@ Handle(_pyHypothesis) _pyGen::FindAlgo( const _pyID& theGeom, const _pyID& theMe //================================================================================ /*! * \brief Find subMesh by ID (entry) - * \param theSubMeshID - The subMesh ID - * \retval Handle(_pySubMesh) - The found subMesh + * \param theSubMeshID - The subMesh ID + * \retval Handle(_pySubMesh) - The found subMesh */ //================================================================================ @@ -1382,8 +1385,8 @@ Handle(_pySubMesh) _pyGen::FindSubMesh( const _pyID& theSubMeshID ) //================================================================================ /*! * \brief Change order of commands in the script - * \param theCmd1 - One command - * \param theCmd2 - Another command + * \param theCmd1 - One command + * \param theCmd2 - Another command */ //================================================================================ @@ -1400,15 +1403,15 @@ void _pyGen::ExchangeCommands( Handle(_pyCommand) theCmd1, Handle(_pyCommand) th int nb1 = theCmd1->GetOrderNb(); theCmd1->SetOrderNb( theCmd2->GetOrderNb() ); theCmd2->SetOrderNb( nb1 ); -// cout << "BECOME " << theCmd1->GetOrderNb() << "\t" << theCmd1->GetString() << endl -// << "BECOME " << theCmd2->GetOrderNb() << "\t" << theCmd2->GetString() << endl << endl; + // cout << "BECOME " << theCmd1->GetOrderNb() << "\t" << theCmd1->GetString() << endl + // << "BECOME " << theCmd2->GetOrderNb() << "\t" << theCmd2->GetString() << endl << endl; } //================================================================================ /*! * \brief Set one command after the other - * \param theCmd - Command to move - * \param theAfterCmd - Command ater which to insert the first one + * \param theCmd - Command to move + * \param theAfterCmd - Command ater which to insert the first one */ //================================================================================ @@ -1420,8 +1423,8 @@ void _pyGen::SetCommandAfter( Handle(_pyCommand) theCmd, Handle(_pyCommand) theA //================================================================================ /*! * \brief Set one command before the other - * \param theCmd - Command to move - * \param theBeforeCmd - Command before which to insert the first one + * \param theCmd - Command to move + * \param theBeforeCmd - Command before which to insert the first one */ //================================================================================ @@ -1433,8 +1436,8 @@ void _pyGen::SetCommandBefore( Handle(_pyCommand) theCmd, Handle(_pyCommand) the //================================================================================ /*! * \brief Set one command before or after the other - * \param theCmd - Command to move - * \param theOtherCmd - Command ater or before which to insert the first one + * \param theCmd - Command to move + * \param theOtherCmd - Command ater or before which to insert the first one */ //================================================================================ @@ -1461,7 +1464,7 @@ void _pyGen::setNeighbourCommand( Handle(_pyCommand)& theCmd, // void _pyGen::addFilterUser( Handle(_pyCommand)& theCommand, const Handle(_pyObject)& user ) // { - // No more needed after adding _pyObject::myArgCommands +// No more needed after adding _pyObject::myArgCommands // const char filterPrefix[] = "aFilter0x"; // if ( theCommand->GetString().Search( filterPrefix ) < 1 ) @@ -1487,7 +1490,7 @@ void _pyGen::setNeighbourCommand( Handle(_pyCommand)& theCmd, //================================================================================ /*! * \brief Set command be last in list of commands - * \param theCmd - Command to be last + * \param theCmd - Command to be last */ //================================================================================ @@ -1499,8 +1502,8 @@ Handle(_pyCommand)& _pyGen::GetLastCommand() //================================================================================ /*! * \brief Set method to access to object wrapped with python class - * \param theID - The wrapped object entry - * \param theMethod - The accessor method + * \param theID - The wrapped object entry + * \param theMethod - The accessor method */ //================================================================================ @@ -1512,7 +1515,7 @@ void _pyGen::SetAccessorMethod(const _pyID& theID, const char* theMethod ) //================================================================================ /*! * \brief Generated new ID for object and assign with existing name - * \param theID - ID of existing object + * \param theID - ID of existing object */ //================================================================================ @@ -1552,7 +1555,7 @@ bool _pyGen::AddObject( Handle(_pyObject)& theObj ) } else if ( theObj->IsKind( STANDARD_TYPE( _pyMeshEditor ))) { add = myMeshEditors.insert( make_pair( theObj->GetID(), - Handle(_pyMeshEditor)::DownCast( theObj ))).second; + Handle(_pyMeshEditor)::DownCast( theObj ))).second; } else { add = myObjects.insert( make_pair( theObj->GetID(), theObj )).second; @@ -1796,7 +1799,7 @@ _pyMesh::_pyMesh(const Handle(_pyCommand) theCreationCmd, const _pyID& meshId): //================================================================================ /*! * \brief Convert an IDL API command of SMESH::SMESH_Mesh to a method call of python Mesh - * \param theCommand - Engine method called for this mesh + * \param theCommand - Engine method called for this mesh */ //================================================================================ @@ -2453,7 +2456,7 @@ void _pyMeshEditor::Process( const Handle(_pyCommand)& theCommand) "ExtrusionAlongPathX","ExtrusionAlongPathObject1D","ExtrusionAlongPathObject2D", "ExtrusionSweepObjects","RotationSweepObjects","ExtrusionAlongPathObjects", "Mirror","MirrorObject","Translate","TranslateObject","Rotate","RotateObject", - "FindCoincidentNodes","MergeNodes","FindEqualElements", + "FindCoincidentNodes","MergeNodes","FindEqualElements","FillHole", "MergeElements","MergeEqualElements","SewFreeBorders","SewConformFreeBorders", "FindCoincidentFreeBorders", "SewCoincidentFreeBorders", "SewBorderToSide","SewSideElements","ChangeElemNodes","GetLastCreatedNodes", @@ -2645,7 +2648,7 @@ bool _pyMeshEditor::CanClear() //================================================================================ /*! * \brief _pyHypothesis constructor - * \param theCreationCmd - + * \param theCreationCmd - */ //================================================================================ @@ -2658,8 +2661,8 @@ _pyHypothesis::_pyHypothesis(const Handle(_pyCommand)& theCreationCmd): //================================================================================ /*! * \brief Creates algorithm or hypothesis - * \param theCreationCmd - The engine command creating a hypothesis - * \retval Handle(_pyHypothesis) - Result _pyHypothesis + * \param theCreationCmd - The engine command creating a hypothesis + * \retval Handle(_pyHypothesis) - Result _pyHypothesis */ //================================================================================ @@ -2748,9 +2751,9 @@ bool _pyHypothesis::IsWrappable(const _pyID& theMesh) const //================================================================================ /*! * \brief Convert the command adding a hypothesis to mesh into a smesh command - * \param theCmd - The command like mesh.AddHypothesis( geom, hypo ) - * \param theAlgo - The algo that can create this hypo - * \retval bool - false if the command can't be converted + * \param theCmd - The command like mesh.AddHypothesis( geom, hypo ) + * \param theAlgo - The algo that can create this hypo + * \retval bool - false if the command can't be converted */ //================================================================================ @@ -2813,7 +2816,7 @@ bool _pyHypothesis::Addition2Creation( const Handle(_pyCommand)& theCmd, //================================================================================ /*! * \brief Remember hypothesis parameter values - * \param theCommand - The called hypothesis method + * \param theCommand - The called hypothesis method */ //================================================================================ @@ -3166,7 +3169,7 @@ void _pyHypothesis::setCreationArg( const int argNb, const _AString& arg ) //================================================================================ /*! * \brief Remember hypothesis parameter values - * \param theCommand - The called hypothesis method + * \param theCommand - The called hypothesis method */ //================================================================================ @@ -3221,8 +3224,8 @@ void _pyComplexParamHypo::Process( const Handle(_pyCommand)& theCommand) { CreationMethod& crMethod = type2meth->second; while ( (int) crMethod.myArgs.size() < i+1 ) - crMethod.myArgs.push_back( "[]" ); - crMethod.myArgs[ i ] = theCommand->GetArg( 1 ); // arg value + crMethod.myArgs.push_back( "[]" ); + crMethod.myArgs[ i ] = theCommand->GetArg( 1 ); // arg value } myArgCommands.push_back( theCommand ); } @@ -3266,7 +3269,7 @@ void _pyComplexParamHypo::Flush() //================================================================================ /*! * \brief Convert methods of 1D hypotheses to my own methods - * \param theCommand - The called hypothesis method + * \param theCommand - The called hypothesis method */ //================================================================================ @@ -3303,9 +3306,9 @@ void _pyLayerDistributionHypo::Process( const Handle(_pyCommand)& theCommand) //================================================================================ /*! * \brief - * \param theAdditionCmd - command to be converted - * \param theMesh - mesh instance - * \retval bool - status + * \param theAdditionCmd - command to be converted + * \param theMesh - mesh instance + * \retval bool - status */ //================================================================================ @@ -3407,9 +3410,9 @@ void _pyLayerDistributionHypo::Flush() //================================================================================ /*! * \brief additionally to Addition2Creation, clears SetDistrType() command - * \param theCmd - AddHypothesis() command - * \param theMesh - mesh to which a hypothesis is added - * \retval bool - conversion result + * \param theCmd - AddHypothesis() command + * \param theMesh - mesh to which a hypothesis is added + * \retval bool - conversion result */ //================================================================================ @@ -3489,9 +3492,9 @@ void _pyNumberOfSegmentsHyp::Flush() /*! * \brief Convert the command adding "SegmentLengthAroundVertex" to mesh * into regular1D.LengthNearVertex( length, vertex ) - * \param theCmd - The command like mesh.AddHypothesis( vertex, SegmentLengthAroundVertex ) - * \param theMesh - The mesh needing this hypo - * \retval bool - false if the command can't be converted + * \param theCmd - The command like mesh.AddHypothesis( vertex, SegmentLengthAroundVertex ) + * \param theMesh - The mesh needing this hypo + * \retval bool - false if the command can't be converted */ //================================================================================ @@ -3534,7 +3537,7 @@ bool _pySegmentLengthAroundVertexHyp::Addition2Creation( const Handle(_pyCommand //================================================================================ /*! * \brief _pyAlgorithm constructor - * \param theCreationCmd - The command like "algo = smeshgen.CreateHypothesis(type,lib)" + * \param theCreationCmd - The command like "algo = smeshgen.CreateHypothesis(type,lib)" */ //================================================================================ @@ -3547,9 +3550,9 @@ _pyAlgorithm::_pyAlgorithm(const Handle(_pyCommand)& theCreationCmd) //================================================================================ /*! * \brief Convert the command adding an algorithm to mesh - * \param theCmd - The command like mesh.AddHypothesis( geom, algo ) - * \param theMesh - The mesh needing this algo - * \retval bool - false if the command can't be converted + * \param theCmd - The command like mesh.AddHypothesis( geom, algo ) + * \param theMesh - The mesh needing this algo + * \retval bool - false if the command can't be converted */ //================================================================================ @@ -3567,8 +3570,8 @@ bool _pyAlgorithm::Addition2Creation( const Handle(_pyCommand)& theCmd, //================================================================================ /*! * \brief Return starting position of a part of python command - * \param thePartIndex - The index of command part - * \retval int - Part position + * \param thePartIndex - The index of command part + * \retval int - Part position */ //================================================================================ @@ -3585,8 +3588,8 @@ int _pyCommand::GetBegPos( int thePartIndex ) const //================================================================================ /*! * \brief Store starting position of a part of python command - * \param thePartIndex - The index of command part - * \param thePosition - Part position + * \param thePartIndex - The index of command part + * \param thePosition - Part position */ //================================================================================ @@ -3601,7 +3604,7 @@ void _pyCommand::SetBegPos( int thePartIndex, int thePosition ) //================================================================================ /*! * \brief Returns whitespace symbols at the line beginning - * \retval TCollection_AsciiString - result + * \retval TCollection_AsciiString - result */ //================================================================================ @@ -3618,7 +3621,7 @@ TCollection_AsciiString _pyCommand::GetIndentation() //================================================================================ /*! * \brief Return substring of python command looking like ResultValue = Obj.Meth() - * \retval const TCollection_AsciiString & - ResultValue substring + * \retval const TCollection_AsciiString & - ResultValue substring */ //================================================================================ @@ -3758,7 +3761,7 @@ const TCollection_AsciiString & _pyCommand::GetObject() //================================================================================ /*! * \brief Return substring of python command looking like ResVal = Obj.Method() - * \retval const TCollection_AsciiString & - Method substring + * \retval const TCollection_AsciiString & - Method substring */ //================================================================================ @@ -3801,7 +3804,7 @@ bool _pyCommand::IsMethodCall() //================================================================================ /*! * \brief Return substring of python command looking like ResVal = Obj.Meth(Arg1,...) - * \retval const TCollection_AsciiString & - Arg substring + * \retval const TCollection_AsciiString & - Arg substring */ //================================================================================ @@ -3902,8 +3905,8 @@ int _pyCommand::GetArgBeginning() const //================================================================================ /*! * \brief Check if char is a word part - * \param c - The character to check - * \retval bool - The check result + * \param c - The character to check + * \retval bool - The check result */ //================================================================================ @@ -3916,10 +3919,10 @@ static inline bool isWord(const char c, const bool dotIsWord) //================================================================================ /*! * \brief Looks for a word in the string and returns word's beginning - * \param theString - The input string - * \param theStartPos - The position to start the search, returning word's beginning - * \param theForward - The search direction - * \retval TCollection_AsciiString - The found word + * \param theString - The input string + * \param theStartPos - The position to start the search, returning word's beginning + * \param theForward - The search direction + * \retval TCollection_AsciiString - The found word */ //================================================================================ @@ -4050,9 +4053,9 @@ std::list< _pyID > _pyCommand::GetStudyEntries( const TCollection_AsciiString& s //================================================================================ /*! * \brief Look for position where not space char is - * \param theString - The string - * \param thePos - The position to search from and which returns result - * \retval bool - false if there are only space after thePos in theString + * \param theString - The string + * \param thePos - The position to search from and which returns result + * \retval bool - false if there are only space after thePos in theString */ //================================================================================ @@ -4070,14 +4073,14 @@ bool _pyCommand::SkipSpaces( const TCollection_AsciiString & theString, int & th //================================================================================ /*! * \brief Modify a part of the command - * \param thePartIndex - The index of the part - * \param thePart - The new part string - * \param theOldPart - The old part + * \param thePartIndex - The index of the part + * \param thePart - The new part string + * \param theOldPart - The old part */ //================================================================================ void _pyCommand::SetPart(int thePartIndex, const TCollection_AsciiString& thePart, - TCollection_AsciiString& theOldPart) + TCollection_AsciiString& theOldPart) { int pos = GetBegPos( thePartIndex ); if ( pos <= Length() && theOldPart != thePart) @@ -4110,8 +4113,8 @@ void _pyCommand::SetPart(int thePartIndex, const TCollection_AsciiString& thePar //================================================================================ /*! * \brief Set agrument - * \param index - The argument index, it counts from 1 - * \param theArg - The argument string + * \param index - The argument index, it counts from 1 + * \param theArg - The argument string */ //================================================================================ @@ -4212,9 +4215,9 @@ bool _pyCommand::SetDependentCmdsAfter() const //================================================================================ /*! * \brief Insert accessor method after theObjectID - * \param theObjectID - id of the accessed object - * \param theAcsMethod - name of the method giving access to the object - * \retval bool - false if theObjectID is not found in the command string + * \param theObjectID - id of the accessed object + * \param theAcsMethod - name of the method giving access to the object + * \retval bool - false if theObjectID is not found in the command string */ //================================================================================ @@ -4302,7 +4305,7 @@ void _pyObject::ClearCommands() //================================================================================ /*! * \brief Return method name giving access to an interaface object wrapped by python class - * \retval const char* - method name + * \retval const char* - method name */ //================================================================================ @@ -4434,39 +4437,39 @@ _pySubMesh::_pySubMesh(const Handle(_pyCommand)& theCreationCmd, bool toKeepAgrC bool _pySubMesh::CanBeArgOfMethod(const _AString& theMethodName) { return false; -// // names of all methods where a sub-mesh can be used as argument -// static TStringSet methods; -// if ( methods.empty() ) { -// const char * names[] = { -// // methods of SMESH_Gen -// "CopyMesh", -// // methods of SMESH_Group -// "AddFrom", -// // methods of SMESH_Measurements -// "MinDistance", -// // methods of SMESH_Mesh -// "ExportPartToMED","ExportCGNS","ExportPartToDAT","ExportPartToUNV","ExportPartToSTL", -// "RemoveSubMesh", -// // methods of SMESH_MeshEditor -// "ReorientObject","Reorient2D","TriToQuadObject","QuadToTriObject","SplitQuadObject", -// "SplitVolumesIntoTetra","SmoothObject","SmoothParametricObject","ConvertFromQuadraticObject", -// "RotationSweepObject","RotationSweepObjectMakeGroups","RotationSweepObject1D", -// "RotationSweepObject1DMakeGroups","RotationSweepObject2D","RotationSweepObject2DMakeGroups", -// "ExtrusionSweepObject","ExtrusionSweepObjectMakeGroups","ExtrusionSweepObject0D", -// "ExtrusionSweepObject0DMakeGroups","ExtrusionSweepObject1D","ExtrusionSweepObject2D", -// "ExtrusionSweepObject1DMakeGroups","ExtrusionSweepObject2DMakeGroups", -// "ExtrusionAlongPathObjX","ExtrusionAlongPathObject","ExtrusionAlongPathObjectMakeGroups", -// "ExtrusionAlongPathObject1D","ExtrusionAlongPathObject1DMakeGroups", -// "ExtrusionAlongPathObject2D","ExtrusionAlongPathObject2DMakeGroups","MirrorObject", -// "MirrorObjectMakeGroups","MirrorObjectMakeMesh","TranslateObject","Scale", -// "TranslateObjectMakeGroups","TranslateObjectMakeMesh","ScaleMakeGroups","ScaleMakeMesh", -// "RotateObject","RotateObjectMakeGroups","RotateObjectMakeMesh","FindCoincidentNodesOnPart", -// "FindCoincidentNodesOnPartBut","FindEqualElements","FindAmongElementsByPoint", -// "MakeBoundaryMesh","Create0DElementsOnAllNodes", -// "" }; // <- mark of end -// methods.Insert( names ); -// } -// return methods.Contains( theMethodName ); + // names of all methods where a sub-mesh can be used as argument + // static TStringSet methods; + // if ( methods.empty() ) { + // const char * names[] = { + // // methods of SMESH_Gen + // "CopyMesh", + // // methods of SMESH_Group + // "AddFrom", + // // methods of SMESH_Measurements + // "MinDistance", + // // methods of SMESH_Mesh + // "ExportPartToMED","ExportCGNS","ExportPartToDAT","ExportPartToUNV","ExportPartToSTL", + // "RemoveSubMesh", + // // methods of SMESH_MeshEditor + // "ReorientObject","Reorient2D","TriToQuadObject","QuadToTriObject","SplitQuadObject", + // "SplitVolumesIntoTetra","SmoothObject","SmoothParametricObject","ConvertFromQuadraticObject", + // "RotationSweepObject","RotationSweepObjectMakeGroups","RotationSweepObject1D", + // "RotationSweepObject1DMakeGroups","RotationSweepObject2D","RotationSweepObject2DMakeGroups", + // "ExtrusionSweepObject","ExtrusionSweepObjectMakeGroups","ExtrusionSweepObject0D", + // "ExtrusionSweepObject0DMakeGroups","ExtrusionSweepObject1D","ExtrusionSweepObject2D", + // "ExtrusionSweepObject1DMakeGroups","ExtrusionSweepObject2DMakeGroups", + // "ExtrusionAlongPathObjX","ExtrusionAlongPathObject","ExtrusionAlongPathObjectMakeGroups", + // "ExtrusionAlongPathObject1D","ExtrusionAlongPathObject1DMakeGroups", + // "ExtrusionAlongPathObject2D","ExtrusionAlongPathObject2DMakeGroups","MirrorObject", + // "MirrorObjectMakeGroups","MirrorObjectMakeMesh","TranslateObject","Scale", + // "TranslateObjectMakeGroups","TranslateObjectMakeMesh","ScaleMakeGroups","ScaleMakeMesh", + // "RotateObject","RotateObjectMakeGroups","RotateObjectMakeMesh","FindCoincidentNodesOnPart", + // "FindCoincidentNodesOnPartBut","FindEqualElements","FindAmongElementsByPoint", + // "MakeBoundaryMesh","Create0DElementsOnAllNodes", + // "" }; // <- mark of end + // methods.Insert( names ); + // } + // return methods.Contains( theMethodName ); } //================================================================================ @@ -4533,13 +4536,13 @@ _pyGroup::_pyGroup(const Handle(_pyCommand)& theCreationCmd, const _pyID & id) //} //else { // ------------------------->>>>> GroupOnGeom( geom, name, typ ) - _pyID type = theCreationCmd->GetArg( 1 ); - _pyID name = theCreationCmd->GetArg( 2 ); - theCreationCmd->SetMethod( "GroupOnGeom" ); - theCreationCmd->RemoveArgs(); - theCreationCmd->SetArg( 1, geom ); - theCreationCmd->SetArg( 2, name ); - theCreationCmd->SetArg( 3, type ); + _pyID type = theCreationCmd->GetArg( 1 ); + _pyID name = theCreationCmd->GetArg( 2 ); + theCreationCmd->SetMethod( "GroupOnGeom" ); + theCreationCmd->RemoveArgs(); + theCreationCmd->SetArg( 1, geom ); + theCreationCmd->SetArg( 2, name ); + theCreationCmd->SetArg( 3, type ); //} } else if ( method == "CreateGroupFromFilter" ) diff --git a/src/SMESH_I/SMESH_2smeshpy.hxx b/src/SMESH_I/SMESH_2smeshpy.hxx index 589c78317..fa86d8682 100644 --- a/src/SMESH_I/SMESH_2smeshpy.hxx +++ b/src/SMESH_I/SMESH_2smeshpy.hxx @@ -40,8 +40,6 @@ #include #include -#include - #include #include CORBA_CLIENT_HEADER(SALOMEDS) @@ -160,7 +158,7 @@ public: bool AddAccessorMethod( _pyID theObjectID, const char* theAcsMethod ); - OCCT_DEFINE_STANDARD_RTTIEXT(_pyCommand,Standard_Transient) + DEFINE_STANDARD_RTTIEXT(_pyCommand,Standard_Transient) }; // ------------------------------------------------------------------------------------- @@ -200,7 +198,7 @@ public: virtual void ClearCommands(); virtual void Free() {} - OCCT_DEFINE_STANDARD_RTTIEXT(_pyObject,Standard_Transient) + DEFINE_STANDARD_RTTIEXT(_pyObject,Standard_Transient) }; // ------------------------------------------------------------------------------------- @@ -329,7 +327,7 @@ private: std::map< _AString, ExportedMeshData > myFile2ExportedMesh; Handle( _pyHypothesisReader ) myHypReader; - OCCT_DEFINE_STANDARD_RTTIEXT(_pyGen,_pyObject) + DEFINE_STANDARD_RTTIEXT(_pyGen,_pyObject) }; // ------------------------------------------------------------------------------------- @@ -370,7 +368,7 @@ private: static void AddMeshAccess( const Handle(_pyCommand)& theCommand ) { theCommand->SetObject( theCommand->GetObject() + "." _pyMesh_ACCESS_METHOD ); } - OCCT_DEFINE_STANDARD_RTTIEXT(_pyMesh,_pyObject) + DEFINE_STANDARD_RTTIEXT(_pyMesh,_pyObject) }; #undef _pyMesh_ACCESS_METHOD @@ -390,7 +388,7 @@ public: virtual void Flush() {} virtual bool CanClear(); - OCCT_DEFINE_STANDARD_RTTIEXT(_pyMesh,_pyObject) + DEFINE_STANDARD_RTTIEXT(_pyMeshEditor,_pyObject) }; // ------------------------------------------------------------------------------------- @@ -474,7 +472,7 @@ public: //void ComputeSaved ( const Handle(_pyCommand)& theComputeCommand ); - OCCT_DEFINE_STANDARD_RTTIEXT(_pyHypothesis,_pyObject) + DEFINE_STANDARD_RTTIEXT(_pyHypothesis,_pyObject) }; // ------------------------------------------------------------------------------------- @@ -491,7 +489,7 @@ public: virtual const char* AccessorMethod() const { return "GetAlgorithm()"; } virtual bool IsWrappable(const _pyID& theMesh) { return !myIsWrapped; } - OCCT_DEFINE_STANDARD_RTTIEXT(_pyAlgorithm,_pyHypothesis) + DEFINE_STANDARD_RTTIEXT(_pyAlgorithm,_pyHypothesis) }; // ------------------------------------------------------------------------------------- @@ -506,7 +504,7 @@ public: virtual void Process( const Handle(_pyCommand)& theCommand); virtual void Flush(); - OCCT_DEFINE_STANDARD_RTTIEXT(_pyComplexParamHypo,_pyHypothesis) + DEFINE_STANDARD_RTTIEXT(_pyComplexParamHypo,_pyHypothesis) }; DEFINE_STANDARD_HANDLE (_pyComplexParamHypo, _pyHypothesis); @@ -528,7 +526,7 @@ public: const _pyID& theMesh); virtual void Free() { my1dHyp.Nullify(); } - OCCT_DEFINE_STANDARD_RTTIEXT(_pyLayerDistributionHypo,_pyHypothesis) + DEFINE_STANDARD_RTTIEXT(_pyLayerDistributionHypo,_pyHypothesis) }; DEFINE_STANDARD_HANDLE (_pyLayerDistributionHypo, _pyHypothesis); @@ -545,7 +543,7 @@ public: const _pyID& theMesh); void Flush(); - OCCT_DEFINE_STANDARD_RTTIEXT(_pyNumberOfSegmentsHyp,_pyHypothesis) + DEFINE_STANDARD_RTTIEXT(_pyNumberOfSegmentsHyp,_pyHypothesis) }; DEFINE_STANDARD_HANDLE (_pyNumberOfSegmentsHyp, _pyHypothesis); @@ -560,7 +558,7 @@ public: _pySegmentLengthAroundVertexHyp(const Handle(_pyCommand)& theCrCmd): _pyHypothesis(theCrCmd) {} virtual bool Addition2Creation( const Handle(_pyCommand)& theAdditionCmd, const _pyID& theMesh); - OCCT_DEFINE_STANDARD_RTTIEXT(_pySegmentLengthAroundVertexHyp,_pyHypothesis) + DEFINE_STANDARD_RTTIEXT(_pySegmentLengthAroundVertexHyp,_pyHypothesis) }; DEFINE_STANDARD_HANDLE (_pySegmentLengthAroundVertexHyp, _pyHypothesis); @@ -579,7 +577,7 @@ public: virtual bool CanClear(); static bool IsAliveCmd( const Handle(_pyCommand)& theCmd ); - OCCT_DEFINE_STANDARD_RTTIEXT(_pySelfEraser,_pyObject) + DEFINE_STANDARD_RTTIEXT(_pySelfEraser,_pyObject) }; DEFINE_STANDARD_HANDLE (_pySelfEraser, _pyObject); @@ -601,7 +599,7 @@ public: void SetCreator( const Handle(_pyObject)& theCreator ) { myCreator = theCreator; } static bool CanBeArgOfMethod(const _AString& theMethodName); - OCCT_DEFINE_STANDARD_RTTIEXT(_pySubMesh,_pyObject) + DEFINE_STANDARD_RTTIEXT(_pySubMesh,_pyObject) }; // ------------------------------------------------------------------------------------- /*! @@ -621,7 +619,7 @@ public: //virtual void Free() { myUsers.clear(); } const _pyID& GetNewID() const { return myNewID; } - OCCT_DEFINE_STANDARD_RTTIEXT(_pyFilter,_pyObject) + DEFINE_STANDARD_RTTIEXT(_pyFilter,_pyObject) }; DEFINE_STANDARD_HANDLE (_pyFilter, _pyObject); @@ -642,7 +640,7 @@ public: virtual bool CanClear(); void RemovedWithContents(); - OCCT_DEFINE_STANDARD_RTTIEXT(_pyGroup,_pySubMesh) + DEFINE_STANDARD_RTTIEXT(_pyGroup,_pySubMesh) }; // ------------------------------------------------------------------------------------- @@ -657,7 +655,7 @@ public: _pyHypothesisReader(); Handle(_pyHypothesis) GetHypothesis(const _AString& hypType, const Handle(_pyCommand)& creationCmd) const; - OCCT_DEFINE_STANDARD_RTTIEXT(_pyHypothesisReader,Standard_Transient) + DEFINE_STANDARD_RTTIEXT(_pyHypothesisReader,Standard_Transient) }; #endif diff --git a/src/SMESH_I/SMESH_Filter_i.cxx b/src/SMESH_I/SMESH_Filter_i.cxx index a255fa53f..6b64f7005 100644 --- a/src/SMESH_I/SMESH_Filter_i.cxx +++ b/src/SMESH_I/SMESH_Filter_i.cxx @@ -40,8 +40,6 @@ #include #include -#include - #include #include #include @@ -523,6 +521,21 @@ SMESH::Length2D::Values* Length2D_i::GetValues() return aResult._retn(); } +/* + Class : Deflection2D_i + Description : Functor for calculating distance between a face and geometry +*/ +Deflection2D_i::Deflection2D_i() +{ + myNumericalFunctorPtr.reset( new Controls::Deflection2D() ); + myFunctorPtr = myNumericalFunctorPtr; +} + +FunctorType Deflection2D_i::GetFunctorType() +{ + return SMESH::FT_Deflection2D; +} + /* Class : MultiConnection_i Description : Functor for calculating number of faces conneted to the edge @@ -2094,6 +2107,14 @@ Length2D_ptr FilterManager_i::CreateLength2D() return anObj._retn(); } +Deflection2D_ptr FilterManager_i::CreateDeflection2D() +{ + SMESH::Deflection2D_i* aServant = new SMESH::Deflection2D_i(); + SMESH::Deflection2D_var anObj = aServant->_this(); + TPythonDump()<CreateLength2D(); break; + case SMESH::FT_Deflection2D: + aFunctor = aFilterMgr->CreateDeflection2D(); + break; case SMESH::FT_AspectRatio: aFunctor = aFilterMgr->CreateAspectRatio(); break; @@ -3432,9 +3456,10 @@ static inline LDOMString toString( CORBA::Long theType ) case FT_EqualFaces : return "Equal faces"; case FT_EqualVolumes : return "Equal volumes"; case FT_MultiConnection : return "Borders at multi-connections"; - case FT_MultiConnection2D :return "Borders at multi-connections 2D"; + case FT_MultiConnection2D : return "Borders at multi-connections 2D"; case FT_Length : return "Length"; case FT_Length2D : return "Length 2D"; + case FT_Deflection2D : return "Deflection 2D"; case FT_LessThan : return "Less than"; case FT_MoreThan : return "More than"; case FT_EqualTo : return "Equal to"; @@ -3443,7 +3468,7 @@ static inline LDOMString toString( CORBA::Long theType ) case FT_LogicalOR : return "Or"; case FT_GroupColor : return "Color of Group"; case FT_LinearOrQuadratic : return "Linear or Quadratic"; - case FT_ElemGeomType : return "Element geomtry type"; + case FT_ElemGeomType : return "Element geometry type"; case FT_EntityType : return "Entity type"; case FT_Undefined : return ""; default : return ""; @@ -3483,6 +3508,7 @@ static inline SMESH::FunctorType toFunctorType( const LDOMString& theStr ) // else if ( theStr.equals( "Borders at multi-connections 2D" ) ) return FT_MultiConnection2D; else if ( theStr.equals( "Length" ) ) return FT_Length; // else if ( theStr.equals( "Length2D" ) ) return FT_Length2D; + else if ( theStr.equals( "Deflection" ) ) return FT_Deflection2D; else if ( theStr.equals( "Range of IDs" ) ) return FT_RangeOfIds; else if ( theStr.equals( "Bad Oriented Volume" ) ) return FT_BadOrientedVolume; else if ( theStr.equals( "Volumes with bare border" ) ) return FT_BareBorderVolume; @@ -3497,7 +3523,7 @@ static inline SMESH::FunctorType toFunctorType( const LDOMString& theStr ) else if ( theStr.equals( "Or" ) ) return FT_LogicalOR; else if ( theStr.equals( "Color of Group" ) ) return FT_GroupColor; else if ( theStr.equals( "Linear or Quadratic" ) ) return FT_LinearOrQuadratic; - else if ( theStr.equals( "Element geomtry type" ) ) return FT_ElemGeomType; + else if ( theStr.equals( "Element geometry type" ) ) return FT_ElemGeomType; else if ( theStr.equals( "Entity type" ) ) return FT_EntityType; else if ( theStr.equals( "" ) ) return FT_Undefined; else return FT_Undefined; @@ -3922,16 +3948,6 @@ CORBA::Boolean FilterLibrary_i::Save() if ( myFileName == 0 || strlen( myFileName ) == 0 ) return false; -#if OCC_VERSION_MAJOR < 7 - FILE* aOutFile = fopen( myFileName, "wt" ); - if ( !aOutFile ) - return false; - - LDOM_XmlWriter aWriter( aOutFile ); - aWriter.SetIndentation( 2 ); - aWriter << myDoc; - fclose( aOutFile ); -#else std::filebuf fb; fb.open( myFileName, std::ios::out ); @@ -3941,7 +3957,6 @@ CORBA::Boolean FilterLibrary_i::Save() aWriter.SetIndentation( 2 ); aWriter.Write( os, myDoc ); fb.close(); -#endif TPythonDump()< +#include +#include +#include +#include +#include +#include #include #include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include #include -#include #include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include #include -#include -#include -#include -#include -#include -#include #ifdef WIN32 @@ -62,12 +63,16 @@ #define LoadLib( name ) LoadLibrary( name ) #define GetProc GetProcAddress #define UnLoadLib( handle ) FreeLibrary( handle ); -#else +#else // WIN32 #define LibHandle void* - #define LoadLib( name ) dlopen( name, RTLD_LAZY | RTLD_GLOBAL ) + #ifdef DYNLOAD_LOCAL + #define LoadLib( name ) dlopen( name, RTLD_LAZY | RTLD_LOCAL ) + #else // DYNLOAD_LOCAL + #define LoadLib( name ) dlopen( name, RTLD_LAZY | RTLD_GLOBAL ) + #endif // DYNLOAD_LOCAL #define GetProc dlsym #define UnLoadLib( handle ) dlclose( handle ); -#endif +#endif // WIN32 #include "SMESH_Gen_i.hxx" #include "SMESH_version.h" @@ -3819,7 +3824,7 @@ SALOMEDS::TMPFile* SMESH_Gen_i::Save( SALOMEDS::SComponent_ptr theComponent, // "Face V positions" - V parameter of node on face // Find out nb of nodes on edges and faces - // Collect corresponing sub-meshes + // Collect corresponding sub-meshes int nbEdgeNodes = 0, nbFaceNodes = 0; list aEdgeSM, aFaceSM; // loop on SMESHDS_SubMesh'es @@ -4667,18 +4672,23 @@ bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent, if ( aTopGroup->ExistInternalObject( name_group ) ) { aGroup = new HDFgroup( name_group, aTopGroup ); aGroup->OpenOnDisk(); - // get number of groups - int aNbSubObjects = aGroup->nInternalObjects(); - for ( int j = 0; j < aNbSubObjects; j++ ) { - char name_dataset[ HDF_NAME_MAX_LEN+1 ]; - aGroup->InternalObjectIndentify( j, name_dataset ); - // check if it is an group - if ( string( name_dataset ).substr( 0, 5 ) == string( "Group" ) ) { + // PAL23514: get all names from the HDFgroup to avoid iteration on its contents + // within aGroup->ExistInternalObject( name ) + std::vector< std::string > subNames; + TColStd_MapOfAsciiString mapOfNames; + aGroup->GetAllObjects( subNames ); + for ( size_t iN = 0; iN < subNames.size(); ++iN ) + mapOfNames.Add( subNames[ iN ].c_str() ); + // loop on groups + for ( size_t j = 0; j < subNames.size(); j++ ) { + const std::string& name_dataset = subNames[ j ]; + // check if it is a group + if ( name_dataset.substr( 0, 5 ) == "Group" ) { // --> get group id - int subid = atoi( string( name_dataset ).substr( 5 ).c_str() ); + int subid = atoi( name_dataset.substr( 5 ).c_str() ); if ( subid <= 0 ) continue; - aDataset = new HDFdataset( name_dataset, aGroup ); + aDataset = new HDFdataset( name_dataset.c_str(), aGroup ); aDataset->OpenOnDisk(); // Retrieve actual group name @@ -4691,7 +4701,8 @@ bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent, TopoDS_Shape aShape; char aRefName[ 30 ]; sprintf( aRefName, "Ref on shape %d", subid); - if ( aGroup->ExistInternalObject( aRefName ) ) { + if ( mapOfNames.Contains( aRefName )) + { // load mesh "Ref on shape" - it's an entry to SObject aDataset = new HDFdataset( aRefName, aGroup ); aDataset->OpenOnDisk(); @@ -4712,8 +4723,8 @@ bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent, // Try to read a filter of SMESH_GroupOnFilter SMESH::Filter_var filter; SMESH_PredicatePtr predicate; - std::string hdfGrpName = "Filter " + SMESH_Comment(subid); - if ( aGroup->ExistInternalObject( hdfGrpName.c_str() )) + std::string hdfGrpName = ( SMESH_Comment( "Filter ") << subid ); + if ( mapOfNames.Contains( hdfGrpName.c_str() )) { aDataset = new HDFdataset( hdfGrpName.c_str(), aGroup ); aDataset->OpenOnDisk(); @@ -4754,13 +4765,13 @@ bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent, if ( !aGroupBaseDS ) continue; - aGroupBaseDS->SetStoreName( name_dataset ); + aGroupBaseDS->SetStoreName( name_dataset.c_str() ); // ouv : NPAL12872 // Read color of the group char aGroupColorName[ 30 ]; sprintf( aGroupColorName, "ColorGroup %d", subid); - if ( aGroup->ExistInternalObject( aGroupColorName ) ) + if ( mapOfNames.Contains( aGroupColorName )) { aDataset = new HDFdataset( aGroupColorName, aGroup ); aDataset->OpenOnDisk(); diff --git a/src/SMESH_I/SMESH_Gen_i.hxx b/src/SMESH_I/SMESH_Gen_i.hxx index b67e4f1dd..abeb3777d 100644 --- a/src/SMESH_I/SMESH_Gen_i.hxx +++ b/src/SMESH_I/SMESH_Gen_i.hxx @@ -49,6 +49,7 @@ #include #include #include +#include #include #include @@ -61,56 +62,53 @@ class SALOME_LifeCycleCORBA; // ========================================================== class SMESH_I_EXPORT StudyContext { + typedef NCollection_DataMap< int, std::string > TInt2StringMap; + typedef NCollection_DataMap< int, int > TInt2IntMap; public: // constructor StudyContext() {} - // destructor - ~StudyContext() - { - mapIdToIOR.clear(); - mapIdToId.clear(); - } + // register object in the internal map and return its id int addObject( std::string theIOR ) { int nextId = getNextId(); - mapIdToIOR[ nextId ] = theIOR; + mapIdToIOR.Bind( nextId, theIOR ); return nextId; } // find the object id in the internal map by the IOR int findId( std::string theIOR ) { - std::map::iterator imap; + TInt2StringMap::iterator imap; for ( imap = mapIdToIOR.begin(); imap != mapIdToIOR.end(); ++imap ) { - if ( imap->second == theIOR ) - return imap->first; + if ( *imap == theIOR ) + return imap.Iterator().Key(); } return 0; } // get object's IOR by id std::string getIORbyId( const int theId ) { - if ( mapIdToIOR.find( theId ) != mapIdToIOR.end() ) - return mapIdToIOR[ theId ]; - return std::string( "" ); + if ( mapIdToIOR.IsBound( theId ) ) + return mapIdToIOR( theId ); + return std::string(); } // get object's IOR by old id std::string getIORbyOldId( const int theOldId ) { - if ( mapIdToId.find( theOldId ) != mapIdToId.end() ) - return getIORbyId( mapIdToId[ theOldId ] ); - return std::string( "" ); + if ( mapIdToId.IsBound( theOldId ) ) + return getIORbyId( mapIdToId( theOldId )); + return std::string(); } // maps old object id to the new one (used when restoring data) void mapOldToNew( const int oldId, const int newId ) { - mapIdToId[ oldId ] = newId; + mapIdToId.Bind( oldId, newId ); } // get old id by a new one int getOldId( const int newId ) { - std::map::iterator imap; + TInt2IntMap::iterator imap; for ( imap = mapIdToId.begin(); imap != mapIdToId.end(); ++imap ) { - if ( imap->second == newId ) - return imap->first; + if ( *imap == newId ) + return imap.Iterator().Key(); } return 0; } @@ -120,13 +118,13 @@ private: int getNextId() { int id = 1; - while( mapIdToIOR.find( id ) != mapIdToIOR.end() ) + while( mapIdToIOR.IsBound( id ) ) id++; return id; } - std::map mapIdToIOR; // persistent-to-transient map - std::map mapIdToId; // to translate object from persistent to transient form + TInt2StringMap mapIdToIOR; // persistent-to-transient map + TInt2IntMap mapIdToId; // to translate object from persistent to transient form }; // =========================================================== @@ -565,7 +563,7 @@ public: // Return an object that previously had an oldID template - typename TInterface::_var_type GetObjectByOldId( const int oldID ) + typename TInterface::_var_type GetObjectByOldId( const int oldID ) { if ( myStudyContext ) { std::string ior = myStudyContext->getIORbyOldId( oldID ); diff --git a/src/SMESH_I/SMESH_MeshEditor_i.cxx b/src/SMESH_I/SMESH_MeshEditor_i.cxx index 7cbef4f10..c46ae7d0c 100644 --- a/src/SMESH_I/SMESH_MeshEditor_i.cxx +++ b/src/SMESH_I/SMESH_MeshEditor_i.cxx @@ -64,7 +64,6 @@ #include #include #include -#include #include #include @@ -76,15 +75,8 @@ #include #include -#if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100 -#define NO_CAS_CATCH -#endif - #include - -#ifdef NO_CAS_CATCH #include -#endif #include #include @@ -1151,6 +1143,10 @@ CORBA::Long SMESH_MeshEditor_i::AddVolume(const SMESH::long_array & IDsOfNodes) n[8],n[9],n[10],n[11],n[12],n[13],n[14], n[15],n[16],n[17],n[18],n[19]); break; + case 18:elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],n[6],n[7], + n[8],n[9],n[10],n[11],n[12],n[13],n[14], + n[15],n[16],n[17]); + break; case 27:elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],n[6],n[7], n[8],n[9],n[10],n[11],n[12],n[13],n[14], n[15],n[16],n[17],n[18],n[19], @@ -3108,17 +3104,14 @@ SMESH_MeshEditor_i::mirror(TIDSortedElemSet & theElements, ::SMESH_MeshEditor::PGroupIDs groupIds = getEditor().Transform (*workElements, aTrsf, theCopy, theMakeGroups, theTargetMesh); - if ( theCopy && !myIsPreviewMode) + if ( !myIsPreviewMode ) { if ( theTargetMesh ) - { theTargetMesh->GetMeshDS()->Modified(); - } else - { declareMeshModified( /*isReComputeSafe=*/false ); - } } + return theMakeGroups ? getGroups(groupIds.get()) : 0; SMESH_CATCH( SMESH::throwCorbaException ); @@ -3375,16 +3368,12 @@ SMESH_MeshEditor_i::translate(TIDSortedElemSet & theElements, ::SMESH_MeshEditor::PGroupIDs groupIds = getEditor().Transform (*workElements, aTrsf, theCopy, theMakeGroups, theTargetMesh); - if ( theCopy && !myIsPreviewMode ) + if ( !myIsPreviewMode ) { if ( theTargetMesh ) - { theTargetMesh->GetMeshDS()->Modified(); - } else - { declareMeshModified( /*isReComputeSafe=*/false ); - } } return theMakeGroups ? getGroups(groupIds.get()) : 0; @@ -3632,7 +3621,7 @@ SMESH_MeshEditor_i::rotate(TIDSortedElemSet & theElements, ::SMESH_MeshEditor::PGroupIDs groupIds = getEditor().Transform (*workElements, aTrsf, theCopy, theMakeGroups, theTargetMesh); - if ( theCopy && !myIsPreviewMode) + if ( !myIsPreviewMode) { if ( theTargetMesh ) theTargetMesh->GetMeshDS()->Modified(); else declareMeshModified( /*isReComputeSafe=*/false ); @@ -3893,7 +3882,6 @@ SMESH_MeshEditor_i::scale(SMESH::SMESH_IDSource_ptr theObject, }; gp_Trsf aTrsf; -#if OCC_VERSION_LARGE > 0x06070100 // fight against orthogonalization // aTrsf.SetValues( S[0], 0, 0, thePoint.x * (1-S[0]), // 0, S[1], 0, thePoint.y * (1-S[1]), @@ -3906,13 +3894,6 @@ SMESH_MeshEditor_i::scale(SMESH::SMESH_IDSource_ptr theObject, thePoint.z * (1-S[2])); M.SetDiagonal( S[0], S[1], S[2] ); -#else - double tol = std::numeric_limits::max(); - aTrsf.SetValues( S[0], 0, 0, thePoint.x * (1-S[0]), - 0, S[1], 0, thePoint.y * (1-S[1]), - 0, 0, S[2], thePoint.z * (1-S[2]), tol, tol); -#endif - TIDSortedElemSet copyElements; TIDSortedElemSet* workElements = &elements; if ( myIsPreviewMode ) @@ -3932,7 +3913,7 @@ SMESH_MeshEditor_i::scale(SMESH::SMESH_IDSource_ptr theObject, ::SMESH_MeshEditor::PGroupIDs groupIds = getEditor().Transform (*workElements, aTrsf, theCopy, theMakeGroups, theTargetMesh); - if ( theCopy && !myIsPreviewMode ) + if ( !myIsPreviewMode ) { if ( theTargetMesh ) theTargetMesh->GetMeshDS()->Modified(); else declareMeshModified( /*isReComputeSafe=*/false ); @@ -4009,7 +3990,7 @@ SMESH_MeshEditor_i::ScaleMakeMesh(SMESH::SMESH_IDSource_ptr theObject, // and then "GetGroups" using SMESH_Mesh::GetGroups() TPythonDump pydump; // to prevent dump at mesh creation - mesh = makeMesh( theMeshName ); + mesh = makeMesh( theMeshName ); mesh_i = SMESH::DownCast( mesh ); if ( mesh_i ) @@ -4596,6 +4577,151 @@ CORBA::Short SMESH_MeshEditor_i::GetPointState(CORBA::Double x, return 0; } +//======================================================================= +//function : IsManifold +//purpose : Check if a 2D mesh is manifold +//======================================================================= + +CORBA::Boolean SMESH_MeshEditor_i::IsManifold() + throw (SALOME::SALOME_Exception) +{ + bool isManifold = true; + + SMESH_TRY; + SMESH_MeshAlgos::TFreeBorderVec foundFreeBordes; + SMESH_MeshAlgos::FindFreeBorders( *getMeshDS(), + foundFreeBordes, + /*closedOnly=*/true, + &isManifold ); + SMESH_CATCH( SMESH::throwCorbaException ); + + return isManifold; +} + +//======================================================================= +//function : IsCoherentOrientation2D +//purpose : Check if orientation of 2D elements is coherent +//======================================================================= + +CORBA::Boolean SMESH_MeshEditor_i::IsCoherentOrientation2D() + throw (SALOME::SALOME_Exception) +{ + bool isGoodOri = true; + + SMESH_TRY; + SMESH_MeshAlgos::TFreeBorderVec foundFreeBordes; + SMESH_MeshAlgos::FindFreeBorders( *getMeshDS(), + foundFreeBordes, + /*closedOnly=*/true, + /*isManifold=*/0, + &isGoodOri); + SMESH_CATCH( SMESH::throwCorbaException ); + + return isGoodOri; +} + +//======================================================================= +//function : FindFreeBorders +//purpose : Returns all or only closed FreeBorder's. +//======================================================================= + +SMESH::ListOfFreeBorders* SMESH_MeshEditor_i::FindFreeBorders(CORBA::Boolean closedOnly) + throw (SALOME::SALOME_Exception) +{ + SMESH::ListOfFreeBorders_var resBorders = new SMESH::ListOfFreeBorders; + SMESH_TRY; + + SMESH_MeshAlgos::TFreeBorderVec foundFreeBordes; + SMESH_MeshAlgos::FindFreeBorders( *getMeshDS(), foundFreeBordes, closedOnly ); + + resBorders->length( foundFreeBordes.size() ); + for ( size_t i = 0; i < foundFreeBordes.size(); ++i ) + { + const SMESH_MeshAlgos::TFreeBorder& bordNodes = foundFreeBordes[i]; + SMESH::FreeBorder& bordOut = resBorders[i]; + bordOut.nodeIDs.length( bordNodes.size() ); + for ( size_t iN = 0; iN < bordNodes.size(); ++iN ) + bordOut.nodeIDs[ iN ] = bordNodes[ iN ]->GetID(); + } + + SMESH_CATCH( SMESH::throwCorbaException ); + + return resBorders._retn(); +} + +//======================================================================= +//function : FillHole +//purpose : Fill with 2D elements a hole defined by a FreeBorder. +//======================================================================= + +void SMESH_MeshEditor_i::FillHole(const SMESH::FreeBorder& theHole) + throw (SALOME::SALOME_Exception) +{ + initData(); + + if ( theHole.nodeIDs.length() < 4 ) + THROW_SALOME_CORBA_EXCEPTION("A hole should be bound by at least 3 nodes", SALOME::BAD_PARAM); + if ( theHole.nodeIDs[0] != theHole.nodeIDs[ theHole.nodeIDs.length()-1 ] ) + THROW_SALOME_CORBA_EXCEPTION("Not closed hole boundary. " + "First and last nodes must be same", SALOME::BAD_PARAM); + + SMESH_MeshAlgos::TFreeBorder bordNodes; + bordNodes.resize( theHole.nodeIDs.length() ); + for ( size_t iN = 0; iN < theHole.nodeIDs.length(); ++iN ) + { + bordNodes[ iN ] = getMeshDS()->FindNode( theHole.nodeIDs[ iN ]); + if ( !bordNodes[ iN ] ) + THROW_SALOME_CORBA_EXCEPTION(SMESH_Comment("Node #") << theHole.nodeIDs[ iN ] + << " does not exist", SALOME::BAD_PARAM); + } + + SMESH_TRY; + + MeshEditor_I::TPreviewMesh* previewMesh = 0; + SMDS_Mesh* meshDS = getMeshDS(); + if ( myIsPreviewMode ) + { + // copy faces sharing nodes of theHole + TIDSortedElemSet holeFaces; + previewMesh = getPreviewMesh( SMDSAbs_Face ); + for ( size_t i = 0; i < bordNodes.size(); ++i ) + { + SMDS_ElemIteratorPtr fIt = bordNodes[i]->GetInverseElementIterator( SMDSAbs_Face ); + while ( fIt->more() ) + { + const SMDS_MeshElement* face = fIt->next(); + if ( holeFaces.insert( face ).second ) + previewMesh->Copy( face ); + } + bordNodes[i] = previewMesh->GetMeshDS()->FindNode( bordNodes[i]->GetID() ); + ASSERT( bordNodes[i] ); + } + meshDS = previewMesh->GetMeshDS(); + } + + std::vector newFaces; + SMESH_MeshAlgos::FillHole( bordNodes, *meshDS, newFaces ); + + if ( myIsPreviewMode ) + { + previewMesh->Clear(); + for ( size_t i = 0; i < newFaces.size(); ++i ) + previewMesh->Copy( newFaces[i] ); + } + else + { + getEditor().ClearLastCreated(); + SMESH_SequenceOfElemPtr& aSeq = + const_cast( getEditor().GetLastCreatedElems() ); + for ( size_t i = 0; i < newFaces.size(); ++i ) + aSeq.Append( newFaces[i] ); + + TPythonDump() << this << ".FillHole( SMESH.FreeBorder(" << theHole.nodeIDs << " ))"; + } + + SMESH_CATCH( SMESH::throwCorbaException ); +} + //======================================================================= //function : convError //purpose : @@ -6830,3 +6956,130 @@ CORBA::Long SMESH_MeshEditor_i::MakeBoundaryElements(SMESH::Bnd_Dimension dim, SMESH_CATCH( SMESH::throwCorbaException ); return 0; } + +//================================================================================ +/*! + * \brief Create a polyline consisting of 1D mesh elements each lying on a 2D element of + * the initial mesh. Positions of new nodes are found by cutting the mesh by the + * plane passing through pairs of points specified by each PolySegment structure. + * If there are several paths connecting a pair of points, the shortest path is + * selected by the module. Position of the cutting plane is defined by the two + * points and an optional vector lying on the plane specified by a PolySegment. + * By default the vector is defined by Mesh module as following. A middle point + * of the two given points is computed. The middle point is projected to the mesh. + * The vector goes from the middle point to the projection point. In case of planar + * mesh, the vector is normal to the mesh. + * \param [inout] segments - PolySegment's defining positions of cutting planes. + * Return the used vector and position of the middle point. + * \param [in] groupName - optional name of a group where created mesh segments will + * be added. + */ +//================================================================================ + +void SMESH_MeshEditor_i::MakePolyLine(SMESH::ListOfPolySegments& theSegments, + const char* theGroupName) + throw (SALOME::SALOME_Exception) +{ + if ( theSegments.length() == 0 ) + THROW_SALOME_CORBA_EXCEPTION("No segments given", SALOME::BAD_PARAM ); + if ( myMesh->NbFaces() == 0 ) + THROW_SALOME_CORBA_EXCEPTION("No faces in the mesh", SALOME::BAD_PARAM ); + + SMESH_TRY; + initData(/*deleteSearchers=*/false); + + SMESHDS_Group* groupDS = 0; + SMESHDS_Mesh* meshDS = getMeshDS(); + if ( myIsPreviewMode ) // copy faces to the tmp mesh + { + TPreviewMesh * tmpMesh = getPreviewMesh( SMDSAbs_Edge ); + SMDS_ElemIteratorPtr faceIt = getMeshDS()->elementsIterator( SMDSAbs_Face ); + while ( faceIt->more() ) + tmpMesh->Copy( faceIt->next() ); + meshDS = tmpMesh->GetMeshDS(); + } + else if ( theGroupName[0] ) // find/create a group of segments + { + SMESH_Mesh::GroupIteratorPtr grpIt = myMesh->GetGroups(); + while ( !groupDS && grpIt->more() ) + { + SMESH_Group* group = grpIt->next(); + if ( group->GetGroupDS()->GetType() == SMDSAbs_Edge && + strcmp( group->GetName(), theGroupName ) == 0 ) + { + groupDS = dynamic_cast< SMESHDS_Group* >( group->GetGroupDS() ); + } + } + if ( !groupDS ) + { + SMESH::SMESH_Group_var groupVar = myMesh_i->CreateGroup( SMESH::EDGE, theGroupName ); + + if ( SMESH_Group_i* groupImpl = SMESH::DownCast( groupVar )) + groupDS = dynamic_cast< SMESHDS_Group* >( groupImpl->GetGroupDS() ); + } + } + + // convert input polySegments + ::SMESH_MeshEditor::TListOfPolySegments segments( theSegments.length() ); + for ( CORBA::ULong i = 0; i < theSegments.length(); ++i ) + { + SMESH::PolySegment& segIn = theSegments[ i ]; + ::SMESH_MeshEditor::PolySegment& segOut = segments[ i ]; + segOut.myNode1[0] = meshDS->FindNode( segIn.node1ID1 ); + segOut.myNode2[0] = meshDS->FindNode( segIn.node1ID2 ); + segOut.myNode1[1] = meshDS->FindNode( segIn.node2ID1 ); + segOut.myNode2[1] = meshDS->FindNode( segIn.node2ID2 ); + segOut.myVector.SetCoord( segIn.vector.PS.x, + segIn.vector.PS.y, + segIn.vector.PS.z ); + if ( !segOut.myNode1[0] ) + THROW_SALOME_CORBA_EXCEPTION( SMESH_Comment( "Invalid node ID: ") << segIn.node1ID1, + SALOME::BAD_PARAM ); + if ( !segOut.myNode1[1] ) + THROW_SALOME_CORBA_EXCEPTION( SMESH_Comment( "Invalid node ID: ") << segIn.node2ID1, + SALOME::BAD_PARAM ); + } + + // get a static ElementSearcher + SMESH::SMESH_IDSource_var idSource = SMESH::SMESH_IDSource::_narrow( myMesh_i->_this() ); + theSearchersDeleter.Set( myMesh, getPartIOR( idSource, SMESH::FACE )); + if ( !theElementSearcher ) + theElementSearcher = SMESH_MeshAlgos::GetElementSearcher( *getMeshDS() ); + + // compute + getEditor().MakePolyLine( segments, groupDS, theElementSearcher ); + + // return vectors + if ( myIsPreviewMode ) + { + for ( CORBA::ULong i = 0; i < theSegments.length(); ++i ) + { + SMESH::PolySegment& segOut = theSegments[ i ]; + ::SMESH_MeshEditor::PolySegment& segIn = segments[ i ]; + segOut.vector.PS.x = segIn.myVector.X(); + segOut.vector.PS.y = segIn.myVector.Y(); + segOut.vector.PS.z = segIn.myVector.Z(); + } + } + else + { + TPythonDump() << "_segments = []"; + for ( CORBA::ULong i = 0; i < theSegments.length(); ++i ) + { + SMESH::PolySegment& segIn = theSegments[ i ]; + TPythonDump() << "_segments.append( SMESH.PolySegment( " + << segIn.node1ID1 << ", " + << segIn.node1ID2 << ", " + << segIn.node2ID1 << ", " + << segIn.node2ID2 << ", " + << "smeshBuilder.MakeDirStruct( " + << segIn.vector.PS.x << ", " + << segIn.vector.PS.y << ", " + << segIn.vector.PS.z << ")))"; + } + TPythonDump() << this << ".MakePolyLine( _segments, '" << theGroupName << "')"; + } + meshDS->Modified(); + SMESH_CATCH( SMESH::throwCorbaException ); + return; +} diff --git a/src/SMESH_I/SMESH_MeshEditor_i.hxx b/src/SMESH_I/SMESH_MeshEditor_i.hxx index 74eaa36ad..bcc0dfc64 100644 --- a/src/SMESH_I/SMESH_MeshEditor_i.hxx +++ b/src/SMESH_I/SMESH_MeshEditor_i.hxx @@ -527,7 +527,7 @@ public: SMESH::ElementType type) throw (SALOME::SALOME_Exception); /*! - * Searching among the given elements, return elements of given type + * Searching among the given elements, return elements of given type * where the given point is IN or ON. * 'ALL' type means elements of any type excluding nodes */ @@ -545,6 +545,30 @@ public: CORBA::Short GetPointState(CORBA::Double x, CORBA::Double y, CORBA::Double z) throw (SALOME::SALOME_Exception); + /*! + * Check if a 2D mesh is manifold + */ + CORBA::Boolean IsManifold() + throw (SALOME::SALOME_Exception); + + /*! + * Check if orientation of 2D elements is coherent + */ + CORBA::Boolean IsCoherentOrientation2D() + throw (SALOME::SALOME_Exception); + + /*! + * Returns all or only closed FreeBorder's. + */ + SMESH::ListOfFreeBorders* FindFreeBorders(CORBA::Boolean closedOnly) + throw (SALOME::SALOME_Exception); + + /*! + * Fill with 2D elements a hole defined by a FreeBorder. + */ + void FillHole(const SMESH::FreeBorder& hole) + throw (SALOME::SALOME_Exception); + SMESH::CoincidentFreeBorders* FindCoincidentFreeBorders(CORBA::Double tolerance); CORBA::Short SewCoincidentFreeBorders(const SMESH::CoincidentFreeBorders& freeBorders, CORBA::Boolean createPolygons, @@ -552,35 +576,35 @@ public: throw (SALOME::SALOME_Exception); SMESH::SMESH_MeshEditor::Sew_Error - SewFreeBorders(CORBA::Long FirstNodeID1, - CORBA::Long SecondNodeID1, - CORBA::Long LastNodeID1, - CORBA::Long FirstNodeID2, - CORBA::Long SecondNodeID2, - CORBA::Long LastNodeID2, - CORBA::Boolean CreatePolygons, - CORBA::Boolean CreatePolyedrs) throw (SALOME::SALOME_Exception); + SewFreeBorders(CORBA::Long FirstNodeID1, + CORBA::Long SecondNodeID1, + CORBA::Long LastNodeID1, + CORBA::Long FirstNodeID2, + CORBA::Long SecondNodeID2, + CORBA::Long LastNodeID2, + CORBA::Boolean CreatePolygons, + CORBA::Boolean CreatePolyedrs) throw (SALOME::SALOME_Exception); SMESH::SMESH_MeshEditor::Sew_Error - SewConformFreeBorders(CORBA::Long FirstNodeID1, - CORBA::Long SecondNodeID1, - CORBA::Long LastNodeID1, - CORBA::Long FirstNodeID2, - CORBA::Long SecondNodeID2) throw (SALOME::SALOME_Exception); + SewConformFreeBorders(CORBA::Long FirstNodeID1, + CORBA::Long SecondNodeID1, + CORBA::Long LastNodeID1, + CORBA::Long FirstNodeID2, + CORBA::Long SecondNodeID2) throw (SALOME::SALOME_Exception); SMESH::SMESH_MeshEditor::Sew_Error - SewBorderToSide(CORBA::Long FirstNodeIDOnFreeBorder, - CORBA::Long SecondNodeIDOnFreeBorder, - CORBA::Long LastNodeIDOnFreeBorder, - CORBA::Long FirstNodeIDOnSide, - CORBA::Long LastNodeIDOnSide, - CORBA::Boolean CreatePolygons, - CORBA::Boolean CreatePolyedrs) throw (SALOME::SALOME_Exception); + SewBorderToSide(CORBA::Long FirstNodeIDOnFreeBorder, + CORBA::Long SecondNodeIDOnFreeBorder, + CORBA::Long LastNodeIDOnFreeBorder, + CORBA::Long FirstNodeIDOnSide, + CORBA::Long LastNodeIDOnSide, + CORBA::Boolean CreatePolygons, + CORBA::Boolean CreatePolyedrs) throw (SALOME::SALOME_Exception); SMESH::SMESH_MeshEditor::Sew_Error - SewSideElements(const SMESH::long_array& IDsOfSide1Elements, - const SMESH::long_array& IDsOfSide2Elements, - CORBA::Long NodeID1OfSide1ToMerge, - CORBA::Long NodeID1OfSide2ToMerge, - CORBA::Long NodeID2OfSide1ToMerge, - CORBA::Long NodeID2OfSide2ToMerge) throw (SALOME::SALOME_Exception); + SewSideElements(const SMESH::long_array& IDsOfSide1Elements, + const SMESH::long_array& IDsOfSide2Elements, + CORBA::Long NodeID1OfSide1ToMerge, + CORBA::Long NodeID1OfSide2ToMerge, + CORBA::Long NodeID2OfSide1ToMerge, + CORBA::Long NodeID2OfSide2ToMerge) throw (SALOME::SALOME_Exception); /*! * Set new nodes for given element. @@ -816,7 +840,7 @@ public: const char* groupName, const SMESH::double_array& theNodesCoords, SMESH::array_of_long_array_out GroupsOfNodes) - throw (SALOME::SALOME_Exception); + throw (SALOME::SALOME_Exception); /*! * \brief Generated skin mesh (containing 2D cells) from 3D mesh @@ -844,7 +868,28 @@ public: SMESH::SMESH_Group_out group) throw (SALOME::SALOME_Exception); -private: //!< private methods + /*! + * \brief Create a polyline consisting of 1D mesh elements each lying on a 2D element of + * the initial mesh. Positions of new nodes are found by cutting the mesh by the + * plane passing through pairs of points specified by each PolySegment structure. + * If there are several paths connecting a pair of points, the shortest path is + * selected by the module. Position of the cutting plane is defined by the two + * points and an optional vector lying on the plane specified by a PolySegment. + * By default the vector is defined by Mesh module as following. A middle point + * of the two given points is computed. The middle point is projected to the mesh. + * The vector goes from the middle point to the projection point. In case of planar + * mesh, the vector is normal to the mesh. + * \param [inout] segments - PolySegment's defining positions of cutting planes. + * Return the used vector and position of the middle point. + * \param [in] groupName - optional name of a group where created mesh segments will + * be added. + */ + void MakePolyLine(SMESH::ListOfPolySegments& segments, + const char* groupName) + throw (SALOME::SALOME_Exception); + + + private: //!< private methods ::SMESH_MeshEditor& getEditor(); diff --git a/src/SMESH_I/SMESH_MeshPartDS.hxx b/src/SMESH_I/SMESH_MeshPartDS.hxx index 423dfb067..986ee3c06 100644 --- a/src/SMESH_I/SMESH_MeshPartDS.hxx +++ b/src/SMESH_I/SMESH_MeshPartDS.hxx @@ -27,6 +27,7 @@ #define __SMESH_MeshPartDS_HXX__ #include "SMESHDS_Mesh.hxx" +#include "SMESH_TypeDefs.hxx" #include #include CORBA_SERVER_HEADER(SMESH_Mesh) @@ -55,6 +56,8 @@ public: virtual SMDS_ElemIteratorPtr elementGeomIterator(SMDSAbs_GeometryType type) const; virtual SMDS_ElemIteratorPtr elementEntityIterator(SMDSAbs_EntityType type) const; + virtual const SMDS_MeshElement *FindElement(int IDelem) const; + private: TIDSortedElemSet _elements[ SMDSAbs_NbElementTypes ]; SMESHDS_Mesh* _meshDS; @@ -65,6 +68,17 @@ private: { void Add(const SMDS_MeshElement* e) { SMDS_MeshInfo::addWithPoly( e ); } }; + /*! + * \brief Element holing its ID only + */ + struct TElemID : public SMDS_MeshElement + { + TElemID(int ID) : SMDS_MeshElement( ID ) {} + virtual SMDSAbs_ElementType GetType() const { return SMDSAbs_All; } + virtual SMDSAbs_EntityType GetEntityType() const { return SMDSEntity_Last; } + virtual SMDSAbs_GeometryType GetGeomType() const { return SMDSGeom_NONE; } + virtual vtkIdType GetVtkType() const { return -1; } + }; }; #endif diff --git a/src/SMESH_I/SMESH_Mesh_i.cxx b/src/SMESH_I/SMESH_Mesh_i.cxx index c9c4013ad..0f56d3035 100644 --- a/src/SMESH_I/SMESH_Mesh_i.cxx +++ b/src/SMESH_I/SMESH_Mesh_i.cxx @@ -2970,6 +2970,7 @@ void SMESH_Mesh_i::ExportMED(const char* file, CORBA::Boolean autoDimension) throw(SALOME::SALOME_Exception) { + //MESSAGE("SMESH::MED_VERSION:"<< theVersion); SMESH_TRY; if ( _preMeshInfo ) _preMeshInfo->FullLoadFromFile(); @@ -3544,7 +3545,8 @@ void SMESH_Mesh_i::ExportPartToSTL(::SMESH::SMESH_IDSource_ptr meshPart, void SMESH_Mesh_i::ExportCGNS(::SMESH::SMESH_IDSource_ptr meshPart, const char* file, - CORBA::Boolean overwrite) + CORBA::Boolean overwrite, + CORBA::Boolean groupElemsByType) throw (SALOME::SALOME_Exception) { #ifdef WITH_CGNS @@ -3561,8 +3563,12 @@ void SMESH_Mesh_i::ExportCGNS(::SMESH::SMESH_IDSource_ptr meshPart, CORBA::String_var name = so->GetName(); meshName = name.in(); } + SMESH_TRY; + SMESH_MeshPartDS partDS( meshPart ); - _impl->ExportCGNS(file, &partDS, meshName.c_str() ); + _impl->ExportCGNS(file, &partDS, meshName.c_str(), groupElemsByType ); + + SMESH_CATCH( SMESH::throwCorbaException ); TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportCGNS( " << meshPart<< ", r'" << file << "', " << overwrite << ")"; @@ -6018,6 +6024,7 @@ SMESH_MeshPartDS::SMESH_MeshPartDS(SMESH::SMESH_IDSource_ptr meshPart): SMESH::SMESH_Mesh_var mesh = meshPart->GetMesh(); SMESH_Mesh_i* mesh_i = SMESH::DownCast( mesh ); + mesh_i->Load(); _meshDS = mesh_i->GetImpl().GetMeshDS(); SetPersistentId( _meshDS->GetPersistentId() ); @@ -6087,6 +6094,21 @@ SMESH_MeshPartDS::SMESH_MeshPartDS(const std::list< const SMDS_MeshElement* > & myInfo = tmpInfo; } // ------------------------------------------------------------------------------------- +const SMDS_MeshElement * SMESH_MeshPartDS::FindElement(int IDelem) const +{ + if ( _meshDS ) return _meshDS->FindElement( IDelem ); + + TElemID elem( IDelem ); + for ( int iType = SMDSAbs_Edge; iType < SMDSAbs_NbElementTypes; ++iType ) + if ( !_elements[ iType ].empty() ) + { + TIDSortedElemSet::const_iterator it = _elements[ iType ].find( &elem ); + if ( it != _elements[ iType ].end() ) + return *it; + } + return 0; +} +// ------------------------------------------------------------------------------------- SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementGeomIterator(SMDSAbs_GeometryType geomType) const { if ( _meshDS ) return _meshDS->elementGeomIterator( geomType ); diff --git a/src/SMESH_I/SMESH_Mesh_i.hxx b/src/SMESH_I/SMESH_Mesh_i.hxx index 4e809d7a3..d92889eb5 100644 --- a/src/SMESH_I/SMESH_Mesh_i.hxx +++ b/src/SMESH_I/SMESH_Mesh_i.hxx @@ -238,7 +238,8 @@ public: void ExportSTL( const char* file, bool isascii ) throw (SALOME::SALOME_Exception); void ExportCGNS(SMESH::SMESH_IDSource_ptr meshPart, const char* file, - CORBA::Boolean overwrite) throw (SALOME::SALOME_Exception); + CORBA::Boolean overwrite, + CORBA::Boolean groupElemsByType) throw (SALOME::SALOME_Exception); void ExportGMF(SMESH::SMESH_IDSource_ptr meshPart, const char* file, CORBA::Boolean withRequiredGroups) throw (SALOME::SALOME_Exception); diff --git a/src/SMESH_I/SMESH_Pattern_i.cxx b/src/SMESH_I/SMESH_Pattern_i.cxx index 4f36ddf40..bcea31b0c 100644 --- a/src/SMESH_I/SMESH_Pattern_i.cxx +++ b/src/SMESH_I/SMESH_Pattern_i.cxx @@ -295,9 +295,7 @@ SMESH::point_array* } bool ok = false; try { -#if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100 OCC_CATCH_SIGNALS; -#endif ok = myPattern.Apply( aMesh, fset, theNodeIndexOnKeyPoint1, theReverse ); } catch (Standard_Failure& exc) { diff --git a/src/SMESH_I/SMESH_PreMeshInfo.cxx b/src/SMESH_I/SMESH_PreMeshInfo.cxx index 62930b818..7db67ae58 100644 --- a/src/SMESH_I/SMESH_PreMeshInfo.cxx +++ b/src/SMESH_I/SMESH_PreMeshInfo.cxx @@ -282,10 +282,12 @@ namespace */ //================================================================================ -void SMESH_PreMeshInfo::hdf2meshInfo( const std::string& name, - HDFgroup* hdfGroup) +void SMESH_PreMeshInfo::hdf2meshInfo( const std::string& name, + HDFgroup* hdfGroup, + const TColStd_MapOfAsciiString& allHdfNames) { - if ( hdfGroup->ExistInternalObject( name.c_str()) ) + //if ( hdfGroup->ExistInternalObject( name.c_str()) ) PAL23514 + if ( allHdfNames.Contains( name.c_str() )) { HDFdataset* dataset = new HDFdataset( name.c_str(), hdfGroup ); dataset->OpenOnDisk(); @@ -414,7 +416,17 @@ bool SMESH_PreMeshInfo::readPreInfoFromHDF() HDFgroup* infoHdfGroup = new HDFgroup( hdfGroupName, aFile ); infoHdfGroup->OpenOnDisk(); - _mesh->changePreMeshInfo()->hdf2meshInfo( "Mesh", infoHdfGroup ); + // PAL23514: get all names from the HDFgroup to avoid iteration on its contents + // within aGroup->ExistInternalObject( name ) + TColStd_MapOfAsciiString mapOfNames; + { + std::vector< std::string > subNames; + infoHdfGroup->GetAllObjects( subNames ); + for ( size_t iN = 0; iN < subNames.size(); ++iN ) + mapOfNames.Add( subNames[ iN ].c_str() ); + } + + _mesh->changePreMeshInfo()->hdf2meshInfo( "Mesh", infoHdfGroup, mapOfNames ); // read SMESH_PreMeshInfo of groups map::const_iterator i2group = _mesh->_mapGroups.begin(); @@ -427,7 +439,7 @@ bool SMESH_PreMeshInfo::readPreInfoFromHDF() if ( SMESHDS_GroupBase* group = group_i->GetGroupDS() ) { const std::string name = group->GetStoreName(); - group_i->changePreMeshInfo()->hdf2meshInfo( name, infoHdfGroup ); + group_i->changePreMeshInfo()->hdf2meshInfo( name, infoHdfGroup, mapOfNames ); } } } @@ -439,7 +451,9 @@ bool SMESH_PreMeshInfo::readPreInfoFromHDF() if ( SMESH_subMesh_i* sm = SMESH::DownCast( id2sm->second )) { sm->changePreMeshInfo() = newInstance(); - sm->changePreMeshInfo()->hdf2meshInfo( SMESH_Comment( sm->GetId()), infoHdfGroup ); + sm->changePreMeshInfo()->hdf2meshInfo( SMESH_Comment( sm->GetId()), + infoHdfGroup, + mapOfNames ); } } } diff --git a/src/SMESH_I/SMESH_PreMeshInfo.hxx b/src/SMESH_I/SMESH_PreMeshInfo.hxx index e0469a978..62492c7d4 100644 --- a/src/SMESH_I/SMESH_PreMeshInfo.hxx +++ b/src/SMESH_I/SMESH_PreMeshInfo.hxx @@ -33,6 +33,7 @@ #include CORBA_SERVER_HEADER(SALOMEDS) #include +#include class DriverMED_R_SMESHDS_Mesh; class HDFfile; @@ -101,7 +102,9 @@ private: // reading from the new study, for which SaveToFile() was called bool readPreInfoFromHDF(); - void hdf2meshInfo( const std::string& dataSetName, HDFgroup* infoHdfGroup ); + void hdf2meshInfo( const std::string& dataSetName, + HDFgroup* infoHdfGroup, + const TColStd_MapOfAsciiString& allHdfNames); // reading from the old study, for which SaveToFile() was not called bool readMeshInfo(); diff --git a/src/SMESH_I/SMESH_PythonDump.cxx b/src/SMESH_I/SMESH_PythonDump.cxx index d92f15da7..0052d85e2 100644 --- a/src/SMESH_I/SMESH_PythonDump.cxx +++ b/src/SMESH_I/SMESH_PythonDump.cxx @@ -233,6 +233,7 @@ namespace SMESH case Entity_TriQuad_Hexa: myStream<<"Entity_TriQuad_Hexa"; break; case Entity_Penta: myStream<<"Entity_Penta"; break; case Entity_Quad_Penta: myStream<<"Entity_Quad_Penta"; break; + case Entity_BiQuad_Penta: myStream<<"Entity_BiQuad_Penta"; break; case Entity_Hexagonal_Prism: myStream<<"Entity_Hexagonal_Prism"; break; case Entity_Polyhedra: myStream<<"Entity_Polyhedra"; break; case Entity_Quad_Polyhedra: myStream<<"Entity_Quad_Polyhedra"; break; @@ -426,6 +427,7 @@ namespace SMESH case FT_MultiConnection2D: myStream<< "aMultiConnection2D"; break; case FT_Length: myStream<< "aLength"; break; case FT_Length2D: myStream<< "aLength2D"; break; + case FT_Deflection2D: myStream<< "aDeflection2D"; break; case FT_NodeConnectivityNumber:myStream<< "aNodeConnectivityNumber";break; case FT_BelongToMeshGroup: myStream<< "aBelongToMeshGroup"; break; case FT_BelongToGeom: myStream<< "aBelongToGeom"; break; diff --git a/src/SMESH_SWIG/StdMeshersBuilder.py b/src/SMESH_SWIG/StdMeshersBuilder.py index 2a0894a19..a81853eb3 100644 --- a/src/SMESH_SWIG/StdMeshersBuilder.py +++ b/src/SMESH_SWIG/StdMeshersBuilder.py @@ -953,6 +953,10 @@ class StdMeshersBuilder_Prism3D(Mesh_Algorithm): ## doc string of the method # @internal docHelper = "Creates prism 3D algorithm for volumes" + ## flag pointing whether this algorithm should be used by default in dynamic method + # of smeshBuilder.Mesh class + # @internal + isDefault = True ## Private constructor. # @param mesh parent mesh object algorithm is assigned to diff --git a/src/SMESH_SWIG/smeshBuilder.py b/src/SMESH_SWIG/smeshBuilder.py index b60dacbc8..dc7f7de35 100644 --- a/src/SMESH_SWIG/smeshBuilder.py +++ b/src/SMESH_SWIG/smeshBuilder.py @@ -1029,6 +1029,8 @@ class smeshBuilder(SMESH._objref_SMESH_Gen): functor = aFilterMgr.CreateLength() elif theCriterion == FT_Length2D: functor = aFilterMgr.CreateLength2D() + elif theCriterion == FT_Deflection2D: + functor = aFilterMgr.CreateDeflection2D() elif theCriterion == FT_NodeConnectivityNumber: functor = aFilterMgr.CreateNodeConnectivityNumber() elif theCriterion == FT_BallDiameter: @@ -1946,8 +1948,11 @@ class Mesh(metaclass=MeshMeta): # @param f is the file name # @param overwrite boolean parameter for overwriting/not overwriting the file # @param meshPart a part of mesh (group, sub-mesh) to export instead of the mesh + # @param groupElemsByType if true all elements of same entity type are exported at ones, + # else elements are exported in order of their IDs which can cause creation + # of multiple cgns sections # @ingroup l2_impexp - def ExportCGNS(self, f, overwrite=1, meshPart=None): + def ExportCGNS(self, f, overwrite=1, meshPart=None, groupElemsByType=False): unRegister = genObjUnRegister() if isinstance( meshPart, list ): meshPart = self.GetIDSource( meshPart, SMESH.ALL ) @@ -1956,7 +1961,7 @@ class Mesh(metaclass=MeshMeta): meshPart = meshPart.mesh elif not meshPart: meshPart = self.mesh - self.mesh.ExportCGNS(meshPart, f, overwrite) + self.mesh.ExportCGNS(meshPart, f, overwrite, groupElemsByType) ## Export the mesh in a file in GMF format. # GMF files must have .mesh extension for the ASCII format and .meshb for @@ -2114,6 +2119,8 @@ class Mesh(metaclass=MeshMeta): # @ingroup l2_grps_create def MakeGroupByIds(self, groupName, elementType, elemIDs): group = self.mesh.CreateGroup(elementType, groupName) + if isinstance( elemIDs, Mesh ): + elemIDs = elemIDs.GetMesh() if hasattr( elemIDs, "GetIDs" ): if hasattr( elemIDs, "SetMesh" ): elemIDs.SetMesh( self.GetMesh() ) @@ -2394,10 +2401,10 @@ class Mesh(metaclass=MeshMeta): return self.editor.MakeIDSource(ids, elemType) - # Get informations about mesh contents: + # Get information about mesh contents: # ------------------------------------ - ## Get the mesh stattistic + ## Get the mesh statistic # @return dictionary type element - count of elements # @ingroup l1_meshinfo def GetMeshInfo(self, obj = None): @@ -3210,6 +3217,16 @@ class Mesh(metaclass=MeshMeta): def GetPointState(self, x, y, z): return self.editor.GetPointState(x, y, z) + ## Check if a 2D mesh is manifold + # @ingroup l1_controls + def IsManifold(self): + return self.editor.IsManifold() + + ## Check if orientation of 2D elements is coherent + # @ingroup l1_controls + def IsCoherentOrientation2D(self): + return self.editor.IsCoherentOrientation2D() + ## Find the node closest to a point and moves it to a point location # @param x the X coordinate of a point # @param y the Y coordinate of a point @@ -3330,7 +3347,7 @@ class Mesh(metaclass=MeshMeta): # Type SMESH.FunctorType._items in the Python Console to see all items. # Note that not all items correspond to numerical functors. # @param MaxAngle is the maximum angle between element normals at which the fusion - # is still performed; theMaxAngle is mesured in radians. + # is still performed; theMaxAngle is measured in radians. # Also it could be a name of variable which defines angle in degrees. # @return TRUE in case of success, FALSE otherwise. # @ingroup l2_modif_unitetri @@ -3349,7 +3366,7 @@ class Mesh(metaclass=MeshMeta): # Type SMESH.FunctorType._items in the Python Console to see all items. # Note that not all items correspond to numerical functors. # @param MaxAngle a max angle between element normals at which the fusion - # is still performed; theMaxAngle is mesured in radians. + # is still performed; theMaxAngle is measured in radians. # @return TRUE in case of success, FALSE otherwise. # @ingroup l2_modif_unitetri def TriToQuadObject (self, theObject, theCriterion, MaxAngle): @@ -4712,6 +4729,24 @@ class Mesh(metaclass=MeshMeta): def MergeEqualElements(self): self.editor.MergeEqualElements() + ## Returns all or only closed free borders + # @return list of SMESH.FreeBorder's + # @ingroup l2_modif_trsf + def FindFreeBorders(self, ClosedOnly=True): + return self.editor.FindFreeBorders( ClosedOnly ) + + ## Fill with 2D elements a hole defined by a SMESH.FreeBorder. + # @param FreeBorder either a SMESH.FreeBorder or a list on node IDs. These nodes + # must describe all sequential nodes of the hole border. The first and the last + # nodes must be the same. Use FindFreeBorders() to get nodes of holes. + # @ingroup l2_modif_trsf + def FillHole(self, holeNodes): + if holeNodes and isinstance( holeNodes, list ) and isinstance( holeNodes[0], int ): + holeNodes = SMESH.FreeBorder(nodeIDs=holeNodes) + if not isinstance( holeNodes, SMESH.FreeBorder ): + raise TypeError("holeNodes must be either SMESH.FreeBorder or list of integer and not %s" % holeNodes) + self.editor.FillHole( holeNodes ) + ## Return groups of FreeBorder's coincident within the given tolerance. # @param tolerance the tolerance. If the tolerance <= 0.0 then one tenth of an average # size of elements adjacent to free borders being compared is used. @@ -4987,12 +5022,12 @@ class Mesh(metaclass=MeshMeta): ## Identify the elements that will be affected by node duplication (actual duplication is not performed. # This method is the first step of DoubleNodeElemGroupsInRegion. - # @param theElems - list of groups of elements (edges or faces) to be replicated + # @param theElems - list of groups of nodes or elements (edges or faces) to be replicated # @param theNodesNot - list of groups of nodes not to replicated # @param theShape - shape to detect affected elements (element which geometric center # located on or inside shape). # The replicated nodes should be associated to affected elements. - # @return groups of affected elements + # @return groups of affected elements in order: volumes, faces, edges # @ingroup l2_modif_duplicat def AffectedElemGroupsInRegion(self, theElems, theNodesNot, theShape): return self.editor.AffectedElemGroupsInRegion(theElems, theNodesNot, theShape) @@ -5027,8 +5062,41 @@ class Mesh(metaclass=MeshMeta): def CreateHoleSkin(self, radius, theShape, groupName, theNodesCoords): return self.editor.CreateHoleSkin( radius, theShape, groupName, theNodesCoords ) - def _getFunctor(self, funcType ): - fn = self.functors[ EnumToLong(funcType) ] + ## Create a polyline consisting of 1D mesh elements each lying on a 2D element of + # the initial mesh. Positions of new nodes are found by cutting the mesh by the + # plane passing through pairs of points specified by each PolySegment structure. + # If there are several paths connecting a pair of points, the shortest path is + # selected by the module. Position of the cutting plane is defined by the two + # points and an optional vector lying on the plane specified by a PolySegment. + # By default the vector is defined by Mesh module as following. A middle point + # of the two given points is computed. The middle point is projected to the mesh. + # The vector goes from the middle point to the projection point. In case of planar + # mesh, the vector is normal to the mesh. + # @param segments - PolySegment's defining positions of cutting planes. + # Return the used vector which goes from the middle point to its projection. + # @param groupName - optional name of a group where created mesh segments will + # be added. + # @ingroup l2_modif_duplicat + def MakePolyLine(self, segments, groupName='', isPreview=False ): + editor = self.editor + if isPreview: + editor = self.mesh.GetMeshEditPreviewer() + segmentsRes = editor.MakePolyLine( segments, groupName ) + for i, seg in enumerate( segmentsRes ): + segments[i].vector = seg.vector + if isPreview: + return editor.GetPreviewData() + return None + + ## Return a cached numerical functor by its type. + # @param theCriterion functor type - an item of SMESH.FunctorType enumeration. + # Type SMESH.FunctorType._items in the Python Console to see all items. + # Note that not all items correspond to numerical functors. + # @return SMESH_NumericalFunctor. The functor is already initialized + # with a mesh + # @ingroup l1_measurements + def GetFunctor(self, funcType ): + fn = self.functors[ funcType._v ] if not fn: fn = self.smeshpyD.GetFunctor(funcType) fn.SetMesh(self.mesh) @@ -5043,7 +5111,7 @@ class Mesh(metaclass=MeshMeta): # @return the functor value or zero in case of invalid arguments # @ingroup l1_measurements def FunctorValue(self, funcType, elemId, isElem=True): - fn = self._getFunctor( funcType ) + fn = self.GetFunctor( funcType ) if fn.GetElementType() == self.GetElementType(elemId, isElem): val = fn.GetValue(elemId) else: @@ -5149,7 +5217,7 @@ class Mesh(metaclass=MeshMeta): unRegister.set( meshPart ) if isinstance( meshPart, Mesh ): meshPart = meshPart.mesh - fun = self._getFunctor( funType ) + fun = self.GetFunctor( funType ) if fun: if meshPart: if hasattr( meshPart, "SetMesh" ): diff --git a/src/SMESH_SWIG_WITHIHM/libSMESH_Swig.cxx b/src/SMESH_SWIG_WITHIHM/libSMESH_Swig.cxx index 6564a8413..a5a5dfe01 100644 --- a/src/SMESH_SWIG_WITHIHM/libSMESH_Swig.cxx +++ b/src/SMESH_SWIG_WITHIHM/libSMESH_Swig.cxx @@ -24,6 +24,7 @@ // #include "libSMESH_Swig.h" +#include #include #include @@ -802,6 +803,25 @@ void SMESH_Swig::EraseActor( const char* Mesh_Entry, const bool allViewers ) ProcessVoidEvent(new TEvent(Mesh_Entry, allViewers)); } +void SMESH_Swig::UpdateActor( const char* Mesh_Entry ) { + class TEvent: public SALOME_Event + { + private: + const char* _entry; + public: + TEvent( const char* Mesh_Entry ) { + _entry = Mesh_Entry; + } + virtual void Execute() { + Handle(SALOME_InteractiveObject) anIO = new SALOME_InteractiveObject + ( _entry, "SMESH", "" ); + SMESH::Update( anIO, true ); + } + }; + + ProcessVoidEvent( new TEvent(Mesh_Entry) ); +} + void SMESH_Swig::SetName(const char* theEntry, const char* theName) { @@ -940,6 +960,78 @@ void SMESH_Swig::select( const char* id, int id1, bool append ) { ProcessVoidEvent( new TSelectListEvent( id, ids, append ) ); } +/*! + \brief Helper class for selection edges of cell event +*/ +class TSelectListOfPairEvent: public SALOME_Event +{ + const char* myId; + std::vector > myIdsList; + bool myIsAppend; + +public: + TSelectListOfPairEvent(const char* id, std::vector > ids, bool append) : + myId(id), + myIdsList(ids), + myIsAppend(append) + {} + virtual void Execute() + { + + LightApp_SelectionMgr* selMgr = 0; + SalomeApp_Application* anApp = dynamic_cast( SUIT_Session::session()->activeApplication() ); + if( anApp ) + selMgr = dynamic_cast( anApp->selectionMgr() ); + + if( !selMgr ) + return; + + selMgr->clearFilters(); + + SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow(); + if(!aViewWindow) + return; + + SMESH_Actor* anActor = SMESH::FindActorByEntry( myId ); + + if (!anActor || !anActor->hasIO()) + return; + + Handle(SALOME_InteractiveObject) anIO = anActor->getIO(); + SALOME_ListIO aList; + aList.Append(anIO); + selMgr->setSelectedObjects(aList, false); + + if ( aViewWindow->SelectionMode() != EdgeOfCellSelection ) { + return; + } + + SVTK_IndexedMapOfIds aMap; + std::vector >::const_iterator anIter; + for (anIter = myIdsList.begin(); anIter != myIdsList.end(); ++anIter) { + std::vector aCompositeId; + aCompositeId.push_back((*anIter).first); + aCompositeId.push_back((*anIter).second); + aMap.Add(aCompositeId); + } + + // Set new selection + SVTK_Selector* aSelector = aViewWindow->GetSelector(); + aSelector->AddOrRemoveCompositeIndex(anIO, aMap, myIsAppend); + aViewWindow->highlight( anIO, true, true ); + aViewWindow->GetInteractor()->onEmitSelectionChanged(); + } +}; + +/*! + \brief Select the elements on the mesh, sub-mesh or group. + \param id object entry + \param ids list of the element ids + \param mode selection mode +*/ +void SMESH_Swig::select( const char* id, std::vector > ids, bool append ) { + ProcessVoidEvent( new TSelectListOfPairEvent( id, ids, append ) ); +} class TGetSelectionModeEvent : public SALOME_Event { @@ -1047,3 +1139,46 @@ public: std::vector SMESH_Swig::getSelected( const char* Mesh_Entry ) { return ProcessEvent( new TGetSelectedEvent(Mesh_Entry) ); } + +class TGetSelectedPairEvent : public SALOME_Event +{ +public: + typedef std::vector > TResult; + TResult myResult; + const char* myId; + + TGetSelectedPairEvent( const char* id) : + myResult( std::vector >() ), + myId(id) + {} + + virtual void Execute() + { + SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow(); + if( !aViewWindow ) + return; + + if(aViewWindow->SelectionMode() != EdgeOfCellSelection ) + return; + + SVTK_Selector* aSelector = aViewWindow->GetSelector(); + if( !aSelector ) + return; + + SMESH_Actor* anActor = SMESH::FindActorByEntry( myId ); + + if ( !anActor || !anActor->hasIO() ) + return; + + SVTK_IndexedMapOfIds aMapIndex; + aSelector->GetCompositeIndex(anActor->getIO(),aMapIndex); + + for( int i = 1; i <= aMapIndex.Extent(); i++ ) + myResult.push_back( std::make_pair( (int)aMapIndex( i )[0], (int)aMapIndex( i )[1]) ); + } +}; + +std::vector > SMESH_Swig::getSelectedEdgeOfCell( const char* Mesh_Entry ) { + return ProcessEvent( new TGetSelectedPairEvent(Mesh_Entry) ); +} + diff --git a/src/SMESH_SWIG_WITHIHM/libSMESH_Swig.h b/src/SMESH_SWIG_WITHIHM/libSMESH_Swig.h index fa157d04a..fa564efa4 100644 --- a/src/SMESH_SWIG_WITHIHM/libSMESH_Swig.h +++ b/src/SMESH_SWIG_WITHIHM/libSMESH_Swig.h @@ -40,6 +40,7 @@ //std includes #include +#include #include @@ -119,6 +120,8 @@ public: void EraseActor( const char*, const bool allViewers = false ); + void UpdateActor( const char* Mesh_Entry ); + /*! * \brief Set mesh icon according to compute status * \param Mesh_Entry - entry of a mesh @@ -131,11 +134,13 @@ public: void setSelectionMode( SelectionMode selectionMode ); std::vector getSelected( const char* Mesh_Entry ); + std::vector > getSelectedEdgeOfCell( const char* Mesh_Entry ); // --------------------- for the test purposes ----------------------- SelectionMode getSelectionMode(); void select( const char *id, std::vector ids, bool append = false ); void select( const char *id, int id1, bool append = false ); + void select( const char *id, std::vector >, bool apend = false ); private: SALOMEDS::StudyBuilder_var myStudyBuilder; diff --git a/src/SMESH_SWIG_WITHIHM/libSMESH_Swig.i b/src/SMESH_SWIG_WITHIHM/libSMESH_Swig.i index 0e323b13f..e261ade1d 100644 --- a/src/SMESH_SWIG_WITHIHM/libSMESH_Swig.i +++ b/src/SMESH_SWIG_WITHIHM/libSMESH_Swig.i @@ -48,9 +48,13 @@ %include "typemaps.i" %include "std_vector.i" +%include "std_pair.i" namespace std { + %template(VectorInt) vector; + %template() std::pair; + %template(PairVector) std::vector >; }; @@ -128,6 +132,11 @@ class SMESH_Swig void CreateAndDisplayActor( const char* Mesh_Entry ); void EraseActor( const char* Mesh_Entry, const bool allViewers = false ); + void UpdateActor( const char* Mesh_Entry ); + + void setSelectionMode( SelectionMode selectionMode); + std::vector getSelected( const char* Mesh_Entry ); + std::vector > getSelectedEdgeOfCell( const char* Mesh_Entry ); actorAspect GetActorAspect(const char* Mesh_Entry, int viewId = 0 ); void SetActorAspect( const actorAspect& actorPres, const char* Mesh_Entry, int viewId = 0 ); @@ -139,5 +148,6 @@ class SMESH_Swig SelectionMode getSelectionMode(); void select( const char *id, std::vector ids, bool append = false ); void select( const char *id, int id1, bool append = false ); + void select( const char *id, std::vector >, bool apend = false ); }; diff --git a/src/StdMeshers/StdMeshers_AutomaticLength.cxx b/src/StdMeshers/StdMeshers_AutomaticLength.cxx index f3fb2428f..9e2ce9748 100644 --- a/src/StdMeshers/StdMeshers_AutomaticLength.cxx +++ b/src/StdMeshers/StdMeshers_AutomaticLength.cxx @@ -191,7 +191,7 @@ namespace { theTShapeToLengthMap.insert( make_pair( getTShape( edge ), L )); } - // Compute S0 - minimal segement length, is computed by the shortest EDGE + // Compute S0 - minimal segment length, is computed by the shortest EDGE /* image attached to PAL10237 diff --git a/src/StdMeshers/StdMeshers_CartesianParameters3D.cxx b/src/StdMeshers/StdMeshers_CartesianParameters3D.cxx index ea5f440cc..0081653ef 100644 --- a/src/StdMeshers/StdMeshers_CartesianParameters3D.cxx +++ b/src/StdMeshers/StdMeshers_CartesianParameters3D.cxx @@ -791,7 +791,7 @@ std::ostream & StdMeshers_CartesianParameters3D::SaveTo(std::ostream & save) //======================================================================= //function : LoadFrom -//purpose : resore my parameters from a stream +//purpose : restore my parameters from a stream //======================================================================= std::istream & StdMeshers_CartesianParameters3D::LoadFrom(std::istream & load) diff --git a/src/StdMeshers/StdMeshers_Cartesian_3D.cxx b/src/StdMeshers/StdMeshers_Cartesian_3D.cxx index cf33157bf..fd0cc1666 100644 --- a/src/StdMeshers/StdMeshers_Cartesian_3D.cxx +++ b/src/StdMeshers/StdMeshers_Cartesian_3D.cxx @@ -36,7 +36,6 @@ #include #include -#include #include @@ -1371,11 +1370,7 @@ namespace } if ( surf->IsKind( STANDARD_TYPE(Geom_BSplineSurface )) || surf->IsKind( STANDARD_TYPE(Geom_BezierSurface ))) -#if OCC_VERSION_MAJOR < 7 - if ( !noSafeTShapes.insert((const Standard_Transient*) _face.TShape() ).second ) -#else if ( !noSafeTShapes.insert( _face.TShape().get() ).second ) -#endif isSafe = false; double f, l; @@ -1415,11 +1410,7 @@ namespace edgeIsSafe = false; } } -#if OCC_VERSION_MAJOR < 7 - if ( !edgeIsSafe && !noSafeTShapes.insert((const Standard_Transient*) e.TShape() ).second ) -#else if ( !edgeIsSafe && !noSafeTShapes.insert( e.TShape().get() ).second ) -#endif isSafe = false; } return isSafe; diff --git a/src/StdMeshers/StdMeshers_Distribution.cxx b/src/StdMeshers/StdMeshers_Distribution.cxx index f1f26aebf..aeef4e1ef 100644 --- a/src/StdMeshers/StdMeshers_Distribution.cxx +++ b/src/StdMeshers/StdMeshers_Distribution.cxx @@ -31,16 +31,9 @@ #include #include -#if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100 -#define NO_CAS_CATCH -#endif - #include #include - -#ifdef NO_CAS_CATCH #include -#endif using namespace std; @@ -60,12 +53,9 @@ bool Function::value( const double, double& f ) const bool ok = true; if (myConv == 0) { try { -#ifdef NO_CAS_CATCH OCC_CATCH_SIGNALS; -#endif f = pow( 10., f ); } catch(Standard_Failure) { - Handle(Standard_Failure) aFail = Standard_Failure::Caught(); f = 0.0; ok = false; } @@ -192,13 +182,10 @@ FunctionExpr::FunctionExpr( const char* str, const int conv ) { bool ok = true; try { -#ifdef NO_CAS_CATCH OCC_CATCH_SIGNALS; -#endif myExpr = ExprIntrp_GenExp::Create(); myExpr->Process( ( Standard_CString )str ); } catch(Standard_Failure) { - Handle(Standard_Failure) aFail = Standard_Failure::Caught(); ok = false; } @@ -228,12 +215,9 @@ bool FunctionExpr::value( const double t, double& f ) const ( ( TColStd_Array1OfReal& )myValues ).ChangeValue( 1 ) = t; bool ok = true; try { -#ifdef NO_CAS_CATCH OCC_CATCH_SIGNALS; -#endif f = myExpr->Expression()->Evaluate( myVars, myValues ); } catch(Standard_Failure) { - Handle(Standard_Failure) aFail = Standard_Failure::Caught(); f = 0.0; ok = false; } @@ -246,9 +230,7 @@ double FunctionExpr::integral( const double a, const double b ) const { double res = 0.0; try { -#ifdef NO_CAS_CATCH OCC_CATCH_SIGNALS; -#endif math_GaussSingleIntegration _int ( *static_cast( const_cast (this) ), a, b, 20 ); if( _int.IsDone() ) diff --git a/src/StdMeshers/StdMeshers_HexaFromSkin_3D.cxx b/src/StdMeshers/StdMeshers_HexaFromSkin_3D.cxx index 13c897d18..32edace13 100644 --- a/src/StdMeshers/StdMeshers_HexaFromSkin_3D.cxx +++ b/src/StdMeshers/StdMeshers_HexaFromSkin_3D.cxx @@ -588,7 +588,7 @@ namespace const SMDS_MeshElement* cornerQuad, const SMDS_MeshNode* nCorner) { - // Find out size of block side mesured in nodes and by the way find two rows + // Find out size of block side measured in nodes and by the way find two rows // of nodes in two directions. int x, y, nbX, nbY; diff --git a/src/StdMeshers/StdMeshers_NumberOfSegments.cxx b/src/StdMeshers/StdMeshers_NumberOfSegments.cxx index b26904eb2..41ba3495e 100644 --- a/src/StdMeshers/StdMeshers_NumberOfSegments.cxx +++ b/src/StdMeshers/StdMeshers_NumberOfSegments.cxx @@ -42,15 +42,8 @@ #include #include -#if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100 -#define NO_CAS_CATCH -#endif - #include - -#ifdef NO_CAS_CATCH #include -#endif #include @@ -237,13 +230,10 @@ void StdMeshers_NumberOfSegments::SetTableFunction(const vector& table) if( _convMode==0 ) { try { -#ifdef NO_CAS_CATCH OCC_CATCH_SIGNALS; -#endif val = pow( 10.0, val ); } catch(Standard_Failure) { - Handle(Standard_Failure) aFail = Standard_Failure::Caught(); throw SALOME_Exception( LOCALIZED( "invalid value")); return; } @@ -334,13 +324,10 @@ bool process( const TCollection_AsciiString& str, int convMode, bool parsed_ok = true; Handle( ExprIntrp_GenExp ) myExpr; try { -#ifdef NO_CAS_CATCH OCC_CATCH_SIGNALS; -#endif myExpr = ExprIntrp_GenExp::Create(); myExpr->Process( str.ToCString() ); } catch(Standard_Failure) { - Handle(Standard_Failure) aFail = Standard_Failure::Caught(); parsed_ok = false; } diff --git a/src/StdMeshers/StdMeshers_Prism_3D.cxx b/src/StdMeshers/StdMeshers_Prism_3D.cxx index d326cd157..894b5c2ef 100644 --- a/src/StdMeshers/StdMeshers_Prism_3D.cxx +++ b/src/StdMeshers/StdMeshers_Prism_3D.cxx @@ -110,6 +110,7 @@ namespace { algo->myProxyMesh.reset( new SMESH_ProxyMesh( *helper->GetMesh() )); algo->myQuadList.clear(); + algo->myHelper = 0; if ( helper ) algo->_quadraticMesh = helper->GetIsQuadratic(); @@ -2586,7 +2587,7 @@ double StdMeshers_Prism_3D::getSweepTolerance( const Prism_3D::TPrismTopo& thePr //======================================================================= //function : isSimpleQuad -//purpose : check if the bottom FACE is meshable with nice qudrangles, +//purpose : check if the bottom FACE is meshable with nice quadrangles, // if so the block aproach can work rather fast. // This is a temporary mean caused by problems in StdMeshers_Sweeper //======================================================================= diff --git a/src/StdMeshers/StdMeshers_ProjectionUtils.cxx b/src/StdMeshers/StdMeshers_ProjectionUtils.cxx index 11f2b5e97..924eba9bf 100644 --- a/src/StdMeshers/StdMeshers_ProjectionUtils.cxx +++ b/src/StdMeshers/StdMeshers_ProjectionUtils.cxx @@ -701,7 +701,7 @@ bool StdMeshers_ProjectionUtils::FindSubShapeAssociation(const TopoDS_Shape& the RETURN_BAD_RESULT("edge2 does not belong to theShape2"); } // - // Look for 2 corresponing faces: + // Look for 2 corresponding faces: // TopoDS_Shape F1, F2; diff --git a/src/StdMeshers/StdMeshers_QuadFromMedialAxis_1D2D.cxx b/src/StdMeshers/StdMeshers_QuadFromMedialAxis_1D2D.cxx index c531c5aae..7b53e6a6d 100644 --- a/src/StdMeshers/StdMeshers_QuadFromMedialAxis_1D2D.cxx +++ b/src/StdMeshers/StdMeshers_QuadFromMedialAxis_1D2D.cxx @@ -603,7 +603,7 @@ namespace theSinuEdges [0].size() > 0 && theSinuEdges [1].size() > 0 ); // the sinuous EDGEs can be composite and C0 continuous, - // therefor we use a complex criterion to find TWO short non-sinuous EDGEs + // therefore we use a complex criterion to find TWO short non-sinuous EDGEs // and the rest EDGEs will be treated as sinuous. // A short edge should have the following features: // a) straight diff --git a/src/StdMeshers/StdMeshers_Quadrangle_2D.cxx b/src/StdMeshers/StdMeshers_Quadrangle_2D.cxx index 300df900e..c3c6d3e96 100644 --- a/src/StdMeshers/StdMeshers_Quadrangle_2D.cxx +++ b/src/StdMeshers/StdMeshers_Quadrangle_2D.cxx @@ -64,17 +64,15 @@ #include "utilities.h" #include "Utils_ExceptHandlers.hxx" -#ifndef StdMeshers_Array2OfNode_HeaderFile -#define StdMeshers_Array2OfNode_HeaderFile -typedef const SMDS_MeshNode* SMDS_MeshNodePtr; -typedef NCollection_Array2 StdMeshers_Array2OfNode; -#endif +#include -using namespace std; +typedef NCollection_Array2 StdMeshers_Array2OfNode; typedef gp_XY gp_UV; typedef SMESH_Comment TComm; +using namespace std; + //============================================================================= /*! * @@ -1010,14 +1008,14 @@ bool StdMeshers_Quadrangle_2D::IsApplicable( const TopoDS_Shape & aShape, bool t continue; } - int nbNoDegenEdges = 0; + int nbNoDegenEdges = 0, totalNbEdges = 0; TopExp_Explorer eExp( aFace, TopAbs_EDGE ); - for ( ; eExp.More() && nbNoDegenEdges < 3; eExp.Next() ) { + for ( ; eExp.More() && nbNoDegenEdges < 3; eExp.Next(), ++totalNbEdges ) { if ( !SMESH_Algo::isDegenerated( TopoDS::Edge( eExp.Current() ))) ++nbNoDegenEdges; } - if ( toCheckAll && nbNoDegenEdges < 3 ) return false; - if ( !toCheckAll && nbNoDegenEdges >= 3 ) return true; + if ( toCheckAll && ( totalNbEdges < 4 && nbNoDegenEdges < 3 )) return false; + if ( !toCheckAll && ( totalNbEdges >= 4 || nbNoDegenEdges >= 3 )) return true; } return ( toCheckAll && nbFoundFaces != 0 ); } @@ -1139,7 +1137,7 @@ FaceQuadStruct::Ptr StdMeshers_Quadrangle_2D::CheckNbEdges(SMESH_Mesh & } } } - else + else //if ( !myHelper || !myHelper->IsRealSeam( edge )) { sideEdges.push_back( edge ); } @@ -3895,173 +3893,179 @@ void StdMeshers_Quadrangle_2D::smooth (FaceQuadStruct::Ptr quad) { // "smooth" by computing node positions using 3D TFI and further projection - int nbhoriz = quad->iSize; - int nbvertic = quad->jSize; - - SMESH_TNodeXYZ a0( quad->UVPt( 0, 0 ).node ); - SMESH_TNodeXYZ a1( quad->UVPt( nbhoriz-1, 0 ).node ); - SMESH_TNodeXYZ a2( quad->UVPt( nbhoriz-1, nbvertic-1 ).node ); - SMESH_TNodeXYZ a3( quad->UVPt( 0, nbvertic-1 ).node ); - - for (int i = 1; i < nbhoriz-1; i++) + list< FaceQuadStruct::Ptr >::iterator q = myQuadList.begin(); + for ( ; q != myQuadList.end() ; ++q ) { - SMESH_TNodeXYZ p0( quad->UVPt( i, 0 ).node ); - SMESH_TNodeXYZ p2( quad->UVPt( i, nbvertic-1 ).node ); - for (int j = 1; j < nbvertic-1; j++) + quad = *q; + int nbhoriz = quad->iSize; + int nbvertic = quad->jSize; + + SMESH_TNodeXYZ a0( quad->UVPt( 0, 0 ).node ); + SMESH_TNodeXYZ a1( quad->UVPt( nbhoriz-1, 0 ).node ); + SMESH_TNodeXYZ a2( quad->UVPt( nbhoriz-1, nbvertic-1 ).node ); + SMESH_TNodeXYZ a3( quad->UVPt( 0, nbvertic-1 ).node ); + + for (int i = 1; i < nbhoriz-1; i++) { - SMESH_TNodeXYZ p1( quad->UVPt( nbhoriz-1, j ).node ); - SMESH_TNodeXYZ p3( quad->UVPt( 0, j ).node ); - - UVPtStruct& uvp = quad->UVPt( i, j ); - - gp_Pnt p = myHelper->calcTFI(uvp.x,uvp.y, a0,a1,a2,a3, p0,p1,p2,p3); - gp_Pnt2d uv = surface->NextValueOfUV( uvp.UV(), p, 10*tol ); - gp_Pnt pnew = surface->Value( uv ); - - meshDS->MoveNode( uvp.node, pnew.X(), pnew.Y(), pnew.Z() ); - uvp.u = uv.X(); - uvp.v = uv.Y(); - } - } - return; - } - - // Get nodes to smooth - - typedef map< const SMDS_MeshNode*, TSmoothNode, TIDCompare > TNo2SmooNoMap; - TNo2SmooNoMap smooNoMap; - - // fixed nodes - set< const SMDS_MeshNode* > fixedNodes; - for ( size_t i = 0; i < myForcedPnts.size(); ++i ) - { - fixedNodes.insert( myForcedPnts[i].node ); - if ( myForcedPnts[i].node->getshapeId() != myHelper->GetSubShapeID() ) - { - TSmoothNode & sNode = smooNoMap[ myForcedPnts[i].node ]; - sNode._uv = myForcedPnts[i].uv; - sNode._xyz = SMESH_TNodeXYZ( myForcedPnts[i].node ); - } - } - SMESHDS_SubMesh* fSubMesh = meshDS->MeshElements( quad->face ); - SMDS_NodeIteratorPtr nIt = fSubMesh->GetNodes(); - while ( nIt->more() ) // loop on nodes bound to a FACE - { - const SMDS_MeshNode* node = nIt->next(); - TSmoothNode & sNode = smooNoMap[ node ]; - sNode._uv = myHelper->GetNodeUV( quad->face, node ); - sNode._xyz = SMESH_TNodeXYZ( node ); - if ( fixedNodes.count( node )) - continue; // fixed - no triangles - - // set sNode._triangles - SMDS_ElemIteratorPtr fIt = node->GetInverseElementIterator( SMDSAbs_Face ); - while ( fIt->more() ) - { - const SMDS_MeshElement* face = fIt->next(); - const int nbN = face->NbCornerNodes(); - const int nInd = face->GetNodeIndex( node ); - const int prevInd = myHelper->WrapIndex( nInd - 1, nbN ); - const int nextInd = myHelper->WrapIndex( nInd + 1, nbN ); - const SMDS_MeshNode* prevNode = face->GetNode( prevInd ); - const SMDS_MeshNode* nextNode = face->GetNode( nextInd ); - sNode._triangles.push_back( TTriangle( & smooNoMap[ prevNode ], - & smooNoMap[ nextNode ])); - } - } - // set _uv of smooth nodes on FACE boundary - set< StdMeshers_FaceSide* > sidesOnEdge; - list< FaceQuadStruct::Ptr >::iterator q = myQuadList.begin(); - for ( ; q != myQuadList.end() ; ++q ) - for ( size_t i = 0; i < (*q)->side.size(); ++i ) - if ( ! (*q)->side[i].grid->Edge(0).IsNull() && - //(*q)->nbNodeOut( i ) == 0 && - sidesOnEdge.insert( (*q)->side[i].grid.get() ).second ) - { - const vector& uvVec = (*q)->side[i].grid->GetUVPtStruct(); - for ( unsigned j = 0; j < uvVec.size(); ++j ) + SMESH_TNodeXYZ p0( quad->UVPt( i, 0 ).node ); + SMESH_TNodeXYZ p2( quad->UVPt( i, nbvertic-1 ).node ); + for (int j = 1; j < nbvertic-1; j++) { - TSmoothNode & sNode = smooNoMap[ uvVec[j].node ]; - sNode._uv = uvVec[j].UV(); - sNode._xyz = SMESH_TNodeXYZ( uvVec[j].node ); + SMESH_TNodeXYZ p1( quad->UVPt( nbhoriz-1, j ).node ); + SMESH_TNodeXYZ p3( quad->UVPt( 0, j ).node ); + + UVPtStruct& uvp = quad->UVPt( i, j ); + + gp_Pnt p = myHelper->calcTFI(uvp.x,uvp.y, a0,a1,a2,a3, p0,p1,p2,p3); + gp_Pnt2d uv = surface->NextValueOfUV( uvp.UV(), p, 10*tol ); + gp_Pnt pnew = surface->Value( uv ); + + meshDS->MoveNode( uvp.node, pnew.X(), pnew.Y(), pnew.Z() ); + uvp.u = uv.X(); + uvp.v = uv.Y(); } } - - // define reference orientation in 2D - TNo2SmooNoMap::iterator n2sn = smooNoMap.begin(); - for ( ; n2sn != smooNoMap.end(); ++n2sn ) - if ( !n2sn->second._triangles.empty() ) - break; - if ( n2sn == smooNoMap.end() ) return; - const TSmoothNode & sampleNode = n2sn->second; - const bool refForward = ( sampleNode._triangles[0].IsForward( sampleNode._uv )); - - // Smoothing - - for ( int iLoop = 0; iLoop < 5; ++iLoop ) + } + } + else { + // Get nodes to smooth + + typedef map< const SMDS_MeshNode*, TSmoothNode, TIDCompare > TNo2SmooNoMap; + TNo2SmooNoMap smooNoMap; + + // fixed nodes + boost::container::flat_set< const SMDS_MeshNode* > fixedNodes; + for ( size_t i = 0; i < myForcedPnts.size(); ++i ) + { + fixedNodes.insert( myForcedPnts[i].node ); + if ( myForcedPnts[i].node->getshapeId() != myHelper->GetSubShapeID() ) + { + TSmoothNode & sNode = smooNoMap[ myForcedPnts[i].node ]; + sNode._uv = myForcedPnts[i].uv; + sNode._xyz = SMESH_TNodeXYZ( myForcedPnts[i].node ); + } + } + SMESHDS_SubMesh* fSubMesh = meshDS->MeshElements( quad->face ); + SMDS_NodeIteratorPtr nIt = fSubMesh->GetNodes(); + while ( nIt->more() ) // loop on nodes bound to a FACE + { + const SMDS_MeshNode* node = nIt->next(); + TSmoothNode & sNode = smooNoMap[ node ]; + sNode._uv = myHelper->GetNodeUV( quad->face, node ); + sNode._xyz = SMESH_TNodeXYZ( node ); + if ( fixedNodes.count( node )) + continue; // fixed - no triangles + + // set sNode._triangles + SMDS_ElemIteratorPtr fIt = node->GetInverseElementIterator( SMDSAbs_Face ); + while ( fIt->more() ) + { + const SMDS_MeshElement* face = fIt->next(); + const int nbN = face->NbCornerNodes(); + const int nInd = face->GetNodeIndex( node ); + const int prevInd = myHelper->WrapIndex( nInd - 1, nbN ); + const int nextInd = myHelper->WrapIndex( nInd + 1, nbN ); + const SMDS_MeshNode* prevNode = face->GetNode( prevInd ); + const SMDS_MeshNode* nextNode = face->GetNode( nextInd ); + sNode._triangles.push_back( TTriangle( & smooNoMap[ prevNode ], + & smooNoMap[ nextNode ])); + } + } + // set _uv of smooth nodes on FACE boundary + set< StdMeshers_FaceSide* > sidesOnEdge; + list< FaceQuadStruct::Ptr >::iterator q = myQuadList.begin(); + for ( ; q != myQuadList.end() ; ++q ) + for ( size_t i = 0; i < (*q)->side.size(); ++i ) + if ( ! (*q)->side[i].grid->Edge(0).IsNull() && + //(*q)->nbNodeOut( i ) == 0 && + sidesOnEdge.insert( (*q)->side[i].grid.get() ).second ) + { + const vector& uvVec = (*q)->side[i].grid->GetUVPtStruct(); + for ( unsigned j = 0; j < uvVec.size(); ++j ) + { + TSmoothNode & sNode = smooNoMap[ uvVec[j].node ]; + sNode._uv = uvVec[j].UV(); + sNode._xyz = SMESH_TNodeXYZ( uvVec[j].node ); + } + } + + // define reference orientation in 2D + TNo2SmooNoMap::iterator n2sn = smooNoMap.begin(); + for ( ; n2sn != smooNoMap.end(); ++n2sn ) + if ( !n2sn->second._triangles.empty() ) + break; + if ( n2sn == smooNoMap.end() ) return; + const TSmoothNode & sampleNode = n2sn->second; + const bool refForward = ( sampleNode._triangles[0].IsForward( sampleNode._uv )); + + // Smoothing + + for ( int iLoop = 0; iLoop < 5; ++iLoop ) + { + for ( n2sn = smooNoMap.begin(); n2sn != smooNoMap.end(); ++n2sn ) + { + TSmoothNode& sNode = n2sn->second; + if ( sNode._triangles.empty() ) + continue; // not movable node + + gp_XY newUV; + bool isValid = false; + bool use3D = ( iLoop > 2 ); // 3 loops in 2D and 2, in 3D + + if ( use3D ) + { + // compute a new XYZ + gp_XYZ newXYZ (0,0,0); + for ( size_t i = 0; i < sNode._triangles.size(); ++i ) + newXYZ += sNode._triangles[i]._n1->_xyz; + newXYZ /= sNode._triangles.size(); + + // compute a new UV by projection + newUV = surface->NextValueOfUV( sNode._uv, newXYZ, 10*tol ).XY(); + + // check validity of the newUV + for ( size_t i = 0; i < sNode._triangles.size() && isValid; ++i ) + isValid = ( sNode._triangles[i].IsForward( newUV ) == refForward ); + } + if ( !isValid ) + { + // compute a new UV by averaging + newUV.SetCoord(0.,0.); + for ( unsigned i = 0; i < sNode._triangles.size(); ++i ) + newUV += sNode._triangles[i]._n1->_uv; + newUV /= sNode._triangles.size(); + + // check validity of the newUV + isValid = true; + for ( unsigned i = 0; i < sNode._triangles.size() && isValid; ++i ) + isValid = ( sNode._triangles[i].IsForward( newUV ) == refForward ); + } + if ( isValid ) + { + sNode._uv = newUV; + sNode._xyz = surface->Value( newUV ).XYZ(); + } + } + } + + // Set new XYZ to the smoothed nodes + for ( n2sn = smooNoMap.begin(); n2sn != smooNoMap.end(); ++n2sn ) { TSmoothNode& sNode = n2sn->second; if ( sNode._triangles.empty() ) continue; // not movable node - gp_XY newUV; - bool isValid = false; - bool use3D = ( iLoop > 2 ); // 3 loops in 2D and 2, in 3D + SMDS_MeshNode* node = const_cast< SMDS_MeshNode*>( n2sn->first ); + gp_Pnt xyz = surface->Value( sNode._uv ); + meshDS->MoveNode( node, xyz.X(), xyz.Y(), xyz.Z() ); - if ( use3D ) - { - // compute a new XYZ - gp_XYZ newXYZ (0,0,0); - for ( size_t i = 0; i < sNode._triangles.size(); ++i ) - newXYZ += sNode._triangles[i]._n1->_xyz; - newXYZ /= sNode._triangles.size(); - - // compute a new UV by projection - newUV = surface->NextValueOfUV( sNode._uv, newXYZ, 10*tol ).XY(); - - // check validity of the newUV - for ( size_t i = 0; i < sNode._triangles.size() && isValid; ++i ) - isValid = ( sNode._triangles[i].IsForward( newUV ) == refForward ); - } - if ( !isValid ) - { - // compute a new UV by averaging - newUV.SetCoord(0.,0.); - for ( unsigned i = 0; i < sNode._triangles.size(); ++i ) - newUV += sNode._triangles[i]._n1->_uv; - newUV /= sNode._triangles.size(); - - // check validity of the newUV - isValid = true; - for ( unsigned i = 0; i < sNode._triangles.size() && isValid; ++i ) - isValid = ( sNode._triangles[i].IsForward( newUV ) == refForward ); - } - if ( isValid ) - { - sNode._uv = newUV; - sNode._xyz = surface->Value( newUV ).XYZ(); - } + // store the new UV + node->SetPosition( SMDS_PositionPtr( new SMDS_FacePosition( sNode._uv.X(), sNode._uv.Y() ))); } } - // Set new XYZ to the smoothed nodes - - for ( n2sn = smooNoMap.begin(); n2sn != smooNoMap.end(); ++n2sn ) - { - TSmoothNode& sNode = n2sn->second; - if ( sNode._triangles.empty() ) - continue; // not movable node - - SMDS_MeshNode* node = const_cast< SMDS_MeshNode*>( n2sn->first ); - gp_Pnt xyz = surface->Value( sNode._uv ); - meshDS->MoveNode( node, xyz.X(), xyz.Y(), xyz.Z() ); - - // store the new UV - node->SetPosition( SMDS_PositionPtr( new SMDS_FacePosition( sNode._uv.X(), sNode._uv.Y() ))); - } - // Move medium nodes in quadratic mesh if ( _quadraticMesh ) { @@ -4085,6 +4089,7 @@ void StdMeshers_Quadrangle_2D::smooth (FaceQuadStruct::Ptr quad) meshDS->MoveNode( node, xyz.X(), xyz.Y(), xyz.Z() ); } } + return; } //================================================================================ @@ -4180,12 +4185,18 @@ bool StdMeshers_Quadrangle_2D::check() if ( myHelper->HasSeam() ) for ( int i = 0; i < nbN && !nInFace; ++i ) if ( !myHelper->IsSeamShape( nn[i]->getshapeId() )) + { nInFace = nn[i]; + gp_XY uv = myHelper->GetNodeUV( geomFace, nInFace ); + if ( myHelper->IsOnSeam( uv )) + nInFace = NULL; + } toCheckUV = true; for ( int i = 0; i < nbN; ++i ) uv[ i ] = myHelper->GetNodeUV( geomFace, nn[i], nInFace, &toCheckUV ); + bool isBad = false; switch ( nbN ) { case 4: { @@ -4198,19 +4209,34 @@ bool StdMeshers_Quadrangle_2D::check() if ( sign1 * sign2 < 0 ) continue; // this should not happen } - if ( sign1 * okSign < 0 ) - badFaces.push_back ( f ); + isBad = ( sign1 * okSign < 0 ); break; } case 3: { double sign = getArea( uv[0], uv[1], uv[2] ); - if ( sign * okSign < 0 ) - badFaces.push_back ( f ); + isBad = ( sign * okSign < 0 ); break; } default:; } + + // if ( isBad && myHelper->HasRealSeam() ) + // { + // // detect a case where a face intersects the seam + // for ( int iPar = 1; iPar < 3; ++iPar ) + // if ( iPar & myHelper->GetPeriodicIndex() ) + // { + // double min = uv[0].Coord( iPar ), max = uv[0].Coord( iPar ); + // for ( int i = 1; i < nbN; ++i ) + // { + // min = Min( min, uv[i].Coord( iPar )); + // max = Max( max, uv[i].Coord( iPar )); + // } + // } + // } + if ( isBad ) + badFaces.push_back ( f ); } if ( !badFaces.empty() ) @@ -4264,7 +4290,7 @@ int StdMeshers_Quadrangle_2D::getCorners(const TopoDS_Face& theFace, if ( SMESH_Algo::isDegenerated( prevE )) { list::reverse_iterator edge = ++theWire.rbegin(); - while ( SMESH_Algo::isDegenerated( *edge )) + while ( SMESH_Algo::isDegenerated( *edge ) /*|| helper.IsRealSeam( *edge )*/) ++edge; if ( edge == theWire.rend() ) return false; @@ -4273,7 +4299,7 @@ int StdMeshers_Quadrangle_2D::getCorners(const TopoDS_Face& theFace, list::iterator edge = theWire.begin(); for ( int iE = 0; edge != theWire.end(); ++edge, ++iE ) { - if ( SMESH_Algo::isDegenerated( *edge )) + if ( SMESH_Algo::isDegenerated( *edge ) /*|| helper.IsRealSeam( *edge )*/) { ++theNbDegenEdges; continue; @@ -4567,7 +4593,7 @@ int StdMeshers_Quadrangle_2D::getCorners(const TopoDS_Face& theFace, { d = Abs( idealLen - accuLength[ iEV ]); - // take into account presence of a coresponding halfDivider + // take into account presence of a corresponding halfDivider const double cornerWgt = 0.5 / nbSides; const double vertexWgt = 0.25 / nbSides; TGeoIndex hd = halfDivider[ evVec[ iEV ]]; diff --git a/src/StdMeshers/StdMeshers_RadialPrism_3D.cxx b/src/StdMeshers/StdMeshers_RadialPrism_3D.cxx index dd533d9b7..2c4fe52ae 100644 --- a/src/StdMeshers/StdMeshers_RadialPrism_3D.cxx +++ b/src/StdMeshers/StdMeshers_RadialPrism_3D.cxx @@ -29,8 +29,6 @@ #include "StdMeshers_RadialPrism_3D.hxx" -#include - #include "StdMeshers_ProjectionUtils.hxx" #include "StdMeshers_NumberOfLayers.hxx" #include "StdMeshers_LayerDistribution.hxx" diff --git a/src/StdMeshers/StdMeshers_RadialQuadrangle_1D2D.cxx b/src/StdMeshers/StdMeshers_RadialQuadrangle_1D2D.cxx index 9828818f9..56e73fc77 100644 --- a/src/StdMeshers/StdMeshers_RadialQuadrangle_1D2D.cxx +++ b/src/StdMeshers/StdMeshers_RadialQuadrangle_1D2D.cxx @@ -668,7 +668,7 @@ public: return true; } // ----------------------------------------------------------------------------- - //! Make mesh on an adge using assigned 1d hyp or defaut nb of segments + //! Make mesh on an adge using assigned 1d hyp or default nb of segments bool ComputeCircularEdge( SMESH_Mesh& aMesh, const StdMeshers_FaceSidePtr& aSide ) { @@ -696,7 +696,7 @@ public: return ok; } // ----------------------------------------------------------------------------- - //! Make mesh on an adge using assigned 1d hyp or defaut nb of segments + //! Make mesh on an adge using assigned 1d hyp or default nb of segments bool EvaluateCircularEdge(SMESH_Mesh& aMesh, const StdMeshers_FaceSidePtr aSide, MapShapeNbElems& aResMap) diff --git a/src/StdMeshers/StdMeshers_Regular_1D.cxx b/src/StdMeshers/StdMeshers_Regular_1D.cxx index d1aa0122d..a555fd432 100644 --- a/src/StdMeshers/StdMeshers_Regular_1D.cxx +++ b/src/StdMeshers/StdMeshers_Regular_1D.cxx @@ -1138,7 +1138,7 @@ bool StdMeshers_Regular_1D::Compute(SMESH_Mesh & theMesh, const TopoDS_Shape & t if ( !nFirst || !nLast ) return error( COMPERR_BAD_INPUT_MESH, "No node on vertex"); - // remove elements created by e.g. patern mapping (PAL21999) + // remove elements created by e.g. pattern mapping (PAL21999) // CLEAN event is incorrectly ptopagated seemingly due to Propagation hyp // so TEMPORARY solution is to clean the submesh manually if (SMESHDS_SubMesh * subMeshDS = meshDS->MeshElements(theShape)) diff --git a/src/StdMeshers/StdMeshers_ViscousLayers.cxx b/src/StdMeshers/StdMeshers_ViscousLayers.cxx index de79cbc62..7b5cbba41 100644 --- a/src/StdMeshers/StdMeshers_ViscousLayers.cxx +++ b/src/StdMeshers/StdMeshers_ViscousLayers.cxx @@ -114,7 +114,7 @@ namespace VISCOUS_3D enum UIndex { U_TGT = 1, U_SRC, LEN_TGT }; const double theMinSmoothCosin = 0.1; - const double theSmoothThickToElemSizeRatio = 0.3; + const double theSmoothThickToElemSizeRatio = 0.6; const double theMinSmoothTriaAngle = 30; const double theMinSmoothQuadAngle = 45; @@ -501,9 +501,11 @@ namespace VISCOUS_3D gp_XY LastUV( const TopoDS_Face& F, _EdgesOnShape& eos, int which=-1 ) const; bool IsOnEdge() const { return _2neibors; } bool IsOnFace() const { return ( _nodes[0]->GetPosition()->GetDim() == 2 ); } + int BaseShapeDim() const { return _nodes[0]->GetPosition()->GetDim(); } gp_XYZ Copy( _LayerEdge& other, _EdgesOnShape& eos, SMESH_MesherHelper& helper ); void SetCosin( double cosin ); void SetNormal( const gp_XYZ& n ) { _normal = n; } + void SetMaxLen( double l ) { _maxLen = l; } int NbSteps() const { return _pos.size() - 1; } // nb inlation steps bool IsNeiborOnEdge( const _LayerEdge* edge ) const; void SetSmooLen( double len ) { // set _len at which smoothing is needed @@ -845,6 +847,8 @@ namespace VISCOUS_3D void Append( const gp_Pnt& center, _LayerEdge* ledge ) { + if ( ledge->Is( _LayerEdge::MULTI_NORMAL )) + return; if ( _curvaCenters.size() > 0 ) _segLength2.push_back( center.SquareDistance( _curvaCenters.back() )); _curvaCenters.push_back( center ); @@ -960,7 +964,7 @@ namespace VISCOUS_3D void limitMaxLenByCurvature( _SolidData& data, SMESH_MesherHelper& helper ); void limitMaxLenByCurvature( _LayerEdge* e1, _LayerEdge* e2, _EdgesOnShape& eos1, _EdgesOnShape& eos2, - SMESH_MesherHelper& helper ); + const bool isSmoothable ); bool updateNormals( _SolidData& data, SMESH_MesherHelper& helper, int stepNb, double stepSize ); bool updateNormalsOfConvexFaces( _SolidData& data, SMESH_MesherHelper& helper, @@ -1085,6 +1089,8 @@ namespace VISCOUS_3D return _eos._edges[ is2nd ? _eos._edges.size()-1 : 0 ]->_2neibors->_edges[ is2nd ]; } bool isAnalytic() const { return !_anaCurve.IsNull(); } + + void offPointsToPython() const; // debug }; //-------------------------------------------------------------------------------- /*! @@ -1604,8 +1610,8 @@ namespace VISCOUS_3D // look for two neighbor not in-FACE nodes of face for ( int i = 0; i < 2; ++i ) { - if ( nNext[i]->GetPosition()->GetDim() != 2 && - nNext[i]->GetID() < nodeOnEdge->GetID() ) + if (( nNext[i]->GetPosition()->GetDim() != 2 ) && + ( nodeOnEdge->GetPosition()->GetDim() == 0 || nNext[i]->GetID() < nodeOnEdge->GetID() )) { // look for an in-FACE node for ( int iN = 0; iN < nbN; ++iN ) @@ -2339,7 +2345,7 @@ bool _ViscousBuilder::findFacesWithLayers(const bool onlyWith) for ( TopoDS_Iterator vIt( edge ); vIt.More(); vIt.Next() ) { TGeomID vID = getMeshDS()->ShapeToIndex( vIt.Value() ); - bool noShrinkV = false; + bool noShrinkV = false, noShrinkIfAdjMeshed = false; if ( iSolid < _sdVec.size() ) { @@ -2349,7 +2355,8 @@ bool _ViscousBuilder::findFacesWithLayers(const bool onlyWith) i2S = _sdVec[i ]._shrinkShape2Shape.find( vID ); i2SAdj = _sdVec[iSolid]._shrinkShape2Shape.find( vID ); if ( i2SAdj == _sdVec[iSolid]._shrinkShape2Shape.end() ) - noShrinkV = ( i2S->second.ShapeType() == TopAbs_EDGE || isStructured ); + noShrinkV = (( isStructured ) || + ( noShrinkIfAdjMeshed = i2S->second.ShapeType() == TopAbs_EDGE )); else noShrinkV = ( ! i2S->second.IsSame( i2SAdj->second )); } @@ -2361,8 +2368,31 @@ bool _ViscousBuilder::findFacesWithLayers(const bool onlyWith) else { // the adjacent SOLID has NO layers at all - noShrinkV = ( isStructured || - _sdVec[i]._shrinkShape2Shape[ vID ].ShapeType() == TopAbs_EDGE ); + if ( isStructured ) + { + noShrinkV = true; + } + else + { + noShrinkV = noShrinkIfAdjMeshed = + ( _sdVec[i]._shrinkShape2Shape[ vID ].ShapeType() == TopAbs_EDGE ); + } + } + + if ( noShrinkV && noShrinkIfAdjMeshed ) + { + // noShrinkV if FACEs in the adjacent SOLID are meshed + PShapeIteratorPtr fIt = helper.GetAncestors( _sdVec[i]._shrinkShape2Shape[ vID ], + *_mesh, TopAbs_FACE, &solid ); + while ( fIt->more() ) + { + const TopoDS_Shape* f = fIt->next(); + if ( !f->IsSame( fWOL )) + { + noShrinkV = ! _mesh->GetSubMesh( *f )->IsEmpty(); + break; + } + } } if ( noShrinkV ) _sdVec[i]._noShrinkShapes.insert( vID ); @@ -2856,7 +2886,7 @@ void _ViscousBuilder::limitStepSizeByCurvature( _SolidData& data ) double curvature = Max( surfProp.MaxCurvature() * oriFactor, surfProp.MinCurvature() * oriFactor ); if ( curvature > minCurvature ) - ledge->_maxLen = Min( ledge->_maxLen, 1. / curvature ); + ledge->SetMaxLen( Min( ledge->_maxLen, 1. / curvature )); } } } @@ -2877,7 +2907,12 @@ void _ViscousBuilder::limitStepSizeByCurvature( _SolidData& data ) for ( size_t j = 0; j < ledge->_simplices.size(); ++j ) if ( ledge->_simplices[j]._nNext->GetPosition()->GetDim() < 2 ) { - convFace._simplexTestEdges.push_back( ledge ); + // do not select _LayerEdge's neighboring sharp EDGEs + bool sharpNbr = false; + for ( size_t iN = 0; iN < ledge->_neibors.size() && !sharpNbr; ++iN ) + sharpNbr = ( ledge->_neibors[iN]->_cosin > theMinSmoothCosin ); + if ( !sharpNbr ) + convFace._simplexTestEdges.push_back( ledge ); break; } } @@ -2931,9 +2966,7 @@ bool _ViscousBuilder::findShapesToSmooth( _SolidData& data ) // Find shapes needing smoothing; such a shape has _LayerEdge._normal on it's // boundary inclined to the shape at a sharp angle - //list< TGeomID > shapesToSmooth; TopTools_MapOfShape edgesOfSmooFaces; - SMESH_MesherHelper helper( *_mesh ); bool ok = true; @@ -2948,32 +2981,34 @@ bool _ViscousBuilder::findShapesToSmooth( _SolidData& data ) continue; double tgtThick = eos._hyp.GetTotalThickness(); - TopExp_Explorer eExp( edgesByGeom[iS]._shape, TopAbs_EDGE ); - for ( ; eExp.More() && !eos._toSmooth; eExp.Next() ) + SMESH_subMeshIteratorPtr subIt = eos._subMesh->getDependsOnIterator(/*includeSelf=*/false ); + while ( subIt->more() && !eos._toSmooth ) { - TGeomID iE = getMeshDS()->ShapeToIndex( eExp.Current() ); - vector<_LayerEdge*>& eE = edgesByGeom[ iE ]._edges; - if ( eE.empty() ) continue; + TGeomID iSub = subIt->next()->GetId(); + const vector<_LayerEdge*>& eSub = edgesByGeom[ iSub ]._edges; + if ( eSub.empty() ) continue; double faceSize; - for ( size_t i = 0; i < eE.size() && !eos._toSmooth; ++i ) - if ( eE[i]->_cosin > theMinSmoothCosin ) + for ( size_t i = 0; i < eSub.size() && !eos._toSmooth; ++i ) + if ( eSub[i]->_cosin > theMinSmoothCosin ) { - SMDS_ElemIteratorPtr fIt = eE[i]->_nodes[0]->GetInverseElementIterator(SMDSAbs_Face); + SMDS_ElemIteratorPtr fIt = eSub[i]->_nodes[0]->GetInverseElementIterator(SMDSAbs_Face); while ( fIt->more() && !eos._toSmooth ) { const SMDS_MeshElement* face = fIt->next(); if ( face->getshapeId() == eos._shapeID && - getDistFromEdge( face, eE[i]->_nodes[0], faceSize )) + getDistFromEdge( face, eSub[i]->_nodes[0], faceSize )) { - eos._toSmooth = needSmoothing( eE[i]->_cosin, tgtThick, faceSize ); + eos._toSmooth = needSmoothing( eSub[i]->_cosin, + tgtThick * eSub[i]->_lenFactor, + faceSize); } } } } if ( eos._toSmooth ) { - for ( eExp.ReInit(); eExp.More(); eExp.Next() ) + for ( TopExp_Explorer eExp( edgesByGeom[iS]._shape, TopAbs_EDGE ); eExp.More(); eExp.Next() ) edgesOfSmooFaces.Add( eExp.Current() ); data.PrepareEdgesToSmoothOnFace( &edgesByGeom[iS], /*substituteSrcNodes=*/false ); @@ -3017,8 +3052,8 @@ bool _ViscousBuilder::findShapesToSmooth( _SolidData& data ) if ( endSeg->getshapeId() == (int) iS ) { double segLen = - SMESH_TNodeXYZ( endSeg->GetNode(0) ).Distance( endSeg->GetNode(1 )); - eos._toSmooth = needSmoothing( cosinAbs, tgtThick, segLen ); + SMESH_TNodeXYZ( endSeg->GetNode( 0 )).Distance( endSeg->GetNode( 1 )); + eos._toSmooth = needSmoothing( cosinAbs, tgtThick * eV[0]->_lenFactor, segLen ); } } if ( eos._toSmooth ) @@ -3042,7 +3077,8 @@ bool _ViscousBuilder::findShapesToSmooth( _SolidData& data ) if ( !eos._hyp.ToSmooth() ) for ( size_t i = 0; i < eos._edges.size(); ++i ) - eos._edges[i]->SetCosin( 0 ); + //eos._edges[i]->SetCosin( 0 ); // keep _cosin to use in limitMaxLenByCurvature() + eos._edges[i]->_lenFactor = 1; } @@ -3106,19 +3142,21 @@ bool _ViscousBuilder::findShapesToSmooth( _SolidData& data ) { _EdgesOnShape* eof = data.GetShapeEdges( *face ); if ( !eof ) continue; // other solid + if ( eos._shapeID == eof->_shapeID ) continue; + if ( !eos.HasC1( eof )) + { + // check the FACEs + eos._eosC1.push_back( eof ); + eof->_toSmooth = false; + data.PrepareEdgesToSmoothOnFace( eof, /*substituteSrcNodes=*/false ); + smQueue.push_back( eof->_subMesh ); + } if ( !eos.HasC1( eoe )) { eos._eosC1.push_back( eoe ); eoe->_toSmooth = false; data.PrepareEdgesToSmoothOnFace( eoe, /*substituteSrcNodes=*/false ); } - if ( eos._shapeID != eof->_shapeID && !eos.HasC1( eof )) - { - eos._eosC1.push_back( eof ); - eof->_toSmooth = false; - data.PrepareEdgesToSmoothOnFace( eof, /*substituteSrcNodes=*/false ); - smQueue.push_back( eof->_subMesh ); - } } } } @@ -3274,6 +3312,7 @@ void _ViscousBuilder::setShapeData( _EdgesOnShape& eos, if ( eos.ShapeType() == TopAbs_FACE ) // get normals to elements on a FACE { SMESHDS_SubMesh* smDS = sm->GetSubMeshDS(); + if ( !smDS ) return; eos._faceNormals.resize( smDS->NbElements() ); SMDS_ElemIteratorPtr eIt = smDS->GetElements(); @@ -3554,7 +3593,7 @@ bool _ViscousBuilder::setEdgeData(_LayerEdge& edge, getMeshDS()->RemoveFreeNode( edge._nodes.back(), 0, /*fromGroups=*/false ); edge._nodes.resize( 1 ); edge._normal.SetCoord( 0,0,0 ); - edge._maxLen = 0; + edge.SetMaxLen( 0 ); } // Set the rest data @@ -4102,6 +4141,8 @@ void _LayerEdge::SetDataByNeighbors( const SMDS_MeshNode* n1, { if ( eos.ShapeType() != TopAbs_EDGE ) return; + if ( _curvature && Is( SMOOTHED_C1 )) + return; gp_XYZ pos = SMESH_TNodeXYZ( _nodes[0] ); gp_XYZ vec1 = pos - SMESH_TNodeXYZ( n1 ); @@ -4375,13 +4416,13 @@ void _ViscousBuilder::computeGeomSize( _SolidData& data ) for ( size_t i = 0; i < eos._edges.size(); ++i ) { if ( eos._edges[i]->Is( _LayerEdge::BLOCKED )) continue; - eos._edges[i]->_maxLen = thinkness; + eos._edges[i]->SetMaxLen( thinkness ); eos._edges[i]->FindIntersection( *searcher, intersecDist, data._epsilon, eos, &face ); if ( intersecDist > 0 && face ) { data._geomSize = Min( data._geomSize, intersecDist ); if ( !neighborFaces.count( face->getshapeId() )) - eos._edges[i]->_maxLen = Min( thinkness, intersecDist / ( face->GetID() < 0 ? 3. : 2. )); + eos[i]->SetMaxLen( Min( thinkness, intersecDist / ( face->GetID() < 0 ? 3. : 2. ))); } } } @@ -4949,6 +4990,7 @@ bool _ViscousBuilder::smoothAndCheck(_SolidData& data, const SMDS_MeshElement* intFace = 0; const SMDS_MeshElement* closestFace = 0; _LayerEdge* le = 0; + bool is1stBlocked = true; // dbg for ( size_t iS = 0; iS < data._edgesOnShape.size(); ++iS ) { _EdgesOnShape& eos = data._edgesOnShape[ iS ]; @@ -5020,7 +5062,7 @@ bool _ViscousBuilder::smoothAndCheck(_SolidData& data, continue; // ignore intersection with intFace of an adjacent FACE - if ( dist > 0 ) + if ( dist > 0.1 * eos._edges[i]->_len ) { bool toIgnore = false; if ( eos._toSmooth ) @@ -5059,6 +5101,9 @@ bool _ViscousBuilder::smoothAndCheck(_SolidData& data, if ( toBlockInfaltion && dist < ( eos._edges[i]->_len * theThickToIntersection )) { + if ( is1stBlocked ) { is1stBlocked = false; // debug + dumpFunction(SMESH_Comment("blockIntersected") <Set( _LayerEdge::INTERSECTED ); // not to intersect eos._edges[i]->Block( data ); // not to inflate @@ -5092,11 +5137,14 @@ bool _ViscousBuilder::smoothAndCheck(_SolidData& data, } // loop on eos._edges } // loop on data._edgesOnShape + if ( !is1stBlocked ) + dumpFunctionEnd(); + if ( closestFace && le ) { #ifdef __myDEBUG SMDS_MeshElement::iterator nIt = closestFace->begin_nodes(); - cout << "Shortest distance: _LayerEdge nodes: tgt " << le->_nodes.back()->GetID() + cout << "#Shortest distance: _LayerEdge nodes: tgt " << le->_nodes.back()->GetID() << " src " << le->_nodes[0]->GetID()<< ", intersection with face (" << (*nIt++)->GetID()<<" "<< (*nIt++)->GetID()<<" "<< (*nIt++)->GetID() << ") distance = " << distToIntersection<< endl; @@ -5290,7 +5338,8 @@ void _ViscousBuilder::makeOffsetSurface( _EdgesOnShape& eos, SMESH_MesherHelper& try { - BRepOffsetAPI_MakeOffsetShape offsetMaker( eos._shape, -offset, Precision::Confusion() ); + BRepOffsetAPI_MakeOffsetShape offsetMaker; + offsetMaker.PerformByJoin( eos._shape, -offset, Precision::Confusion() ); if ( !offsetMaker.IsDone() ) return; TopExp_Explorer fExp( offsetMaker.Shape(), TopAbs_FACE ); @@ -5567,8 +5616,10 @@ void _Smoother1D::findEdgesToSmooth() { if ( !_eos[i]->Is( _LayerEdge::TO_SMOOTH )) { - if ( needSmoothing( _leOnV[0]._cosin, _eos[i]->_len, _curveLen * _leParams[i] ) || - isToSmooth( i )) + if ( needSmoothing( _leOnV[0]._cosin, + _eos[i]->_len * leOnV[0]->_lenFactor, _curveLen * _leParams[i] ) || + isToSmooth( i ) + ) _eos[i]->Set( _LayerEdge::TO_SMOOTH ); else break; @@ -5582,7 +5633,8 @@ void _Smoother1D::findEdgesToSmooth() { if ( !_eos[i]->Is( _LayerEdge::TO_SMOOTH )) { - if ( needSmoothing( _leOnV[1]._cosin, _eos[i]->_len, _curveLen * ( 1.-_leParams[i] )) || + if ( needSmoothing( _leOnV[1]._cosin, + _eos[i]->_len * leOnV[1]->_lenFactor, _curveLen * ( 1.-_leParams[i] )) || isToSmooth( i )) _eos[i]->Set( _LayerEdge::TO_SMOOTH ); else @@ -5923,12 +5975,14 @@ bool _Smoother1D::smoothComplexEdge( _SolidData& data, if ( e[1]->Is( updatedOrBlocked )) _iSeg[1] = _offPoints.size()-2; gp_Pnt pExtreme[2], pProj[2]; + bool isProjected[2]; for ( int is2nd = 0; is2nd < 2; ++is2nd ) { pExtreme[ is2nd ] = SMESH_TNodeXYZ( e[is2nd]->_nodes.back() ); int i = _iSeg[ is2nd ]; int di = is2nd ? -1 : +1; - bool projected = false; + bool & projected = isProjected[ is2nd ]; + projected = false; double uOnSeg, distMin = Precision::Infinite(), dist, distPrev = 0; int nbWorse = 0; do { @@ -5975,7 +6029,7 @@ bool _Smoother1D::smoothComplexEdge( _SolidData& data, gp_Vec vDiv0( pExtreme[0], pProj[0] ); gp_Vec vDiv1( pExtreme[1], pProj[1] ); double d0 = vDiv0.Magnitude(); - double d1 = vDiv1.Magnitude(); + double d1 = isProjected[1] ? vDiv1.Magnitude() : 0; if ( e[0]->Is( _LayerEdge::BLOCKED )) { if ( e[0]->_normal * vDiv0.XYZ() < 0 ) e[0]->_len += d0; else e[0]->_len -= d0; @@ -5989,28 +6043,29 @@ bool _Smoother1D::smoothComplexEdge( _SolidData& data, // compute normalized length of the offset segments located between the projections // --------------------------------------------------------------------------------- + // temporary replace extreme _offPoints by pExtreme + gp_XYZ opXYZ[2] = { _offPoints[ _iSeg[0] ]._xyz, + _offPoints[ _iSeg[1]+1 ]._xyz }; + _offPoints[ _iSeg[0] ]._xyz = pExtreme[0].XYZ(); + _offPoints[ _iSeg[1]+ 1]._xyz = pExtreme[1].XYZ(); + size_t iSeg = 0, nbSeg = _iSeg[1] - _iSeg[0] + 1; vector< double > len( nbSeg + 1 ); len[ iSeg++ ] = 0; - len[ iSeg++ ] = pProj[ 0 ].Distance( _offPoints[ _iSeg[0]+1 ]._xyz )/* * e[0]->_lenFactor*/; + len[ iSeg++ ] = pProj[ 0 ].Distance( _offPoints[ _iSeg[0]+1 ]._xyz ); for ( size_t i = _iSeg[0]+1; i <= _iSeg[1]; ++i, ++iSeg ) { len[ iSeg ] = len[ iSeg-1 ] + _offPoints[i].Distance( _offPoints[i+1] ); } - len[ nbSeg ] -= pProj[ 1 ].Distance( _offPoints[ _iSeg[1]+1 ]._xyz )/* * e[1]->_lenFactor*/; + // if ( isProjected[ 1 ]) + // len[ nbSeg ] -= pProj[ 1 ].Distance( _offPoints[ _iSeg[1]+1 ]._xyz ); + // else + // len[ nbSeg ] += pExtreme[ 1 ].Distance( _offPoints[ _iSeg[1]+1 ]._xyz ); - // d0 *= e[0]->_lenFactor; - // d1 *= e[1]->_lenFactor; double fullLen = len.back() - d0 - d1; for ( iSeg = 0; iSeg < len.size(); ++iSeg ) len[iSeg] = ( len[iSeg] - d0 ) / fullLen; - // temporary replace extreme _offPoints by pExtreme - gp_XYZ op[2] = { _offPoints[ _iSeg[0] ]._xyz, - _offPoints[ _iSeg[1]+1 ]._xyz }; - _offPoints[ _iSeg[0] ]._xyz = pExtreme[0].XYZ(); - _offPoints[ _iSeg[1]+ 1]._xyz = pExtreme[1].XYZ(); - // ------------------------------------------------------------- // distribute tgt nodes of _LayerEdge's between the projections // ------------------------------------------------------------- @@ -6043,8 +6098,8 @@ bool _Smoother1D::smoothComplexEdge( _SolidData& data, dumpMove( tgtNode ); } - _offPoints[ _iSeg[0] ]._xyz = op[0]; - _offPoints[ _iSeg[1]+1 ]._xyz = op[1]; + _offPoints[ _iSeg[0] ]._xyz = opXYZ[0]; + _offPoints[ _iSeg[1]+1 ]._xyz = opXYZ[1]; return true; } @@ -6239,6 +6294,30 @@ gp_XYZ _Smoother1D::getNormalNormal( const gp_XYZ & normal, return norm / size; } +//================================================================================ +/*! + * \brief Writes a script creating a mesh composed of _offPoints + */ +//================================================================================ + +void _Smoother1D::offPointsToPython() const +{ + const char* fname = "/tmp/offPoints.py"; + cout << "execfile('"<_edges.size(); ++i ) - { - eos->_edges[i]->SetSmooLen( Precision::Infinite() ); - } - SMESH_subMeshIteratorPtr smIt = eos->_subMesh->getDependsOnIterator(/*includeSelf=*/false); - while ( smIt->more() ) // loop on sub-shapes of the FACE - { - _EdgesOnShape* eoe = GetShapeEdges( smIt->next()->GetId() ); - if ( !eoe ) continue; + // for ( size_t i = 0; i < eos->_edges.size(); ++i ) + // { + // eos->_edges[i]->SetSmooLen( Precision::Infinite() ); + // } + // SMESH_subMeshIteratorPtr smIt = eos->_subMesh->getDependsOnIterator(/*includeSelf=*/false); + // while ( smIt->more() ) // loop on sub-shapes of the FACE + // { + // _EdgesOnShape* eoe = GetShapeEdges( smIt->next()->GetId() ); + // if ( !eoe ) continue; - vector<_LayerEdge*>& eE = eoe->_edges; - for ( size_t iE = 0; iE < eE.size(); ++iE ) // loop on _LayerEdge's on EDGE or VERTEX - { - if ( eE[iE]->_cosin <= theMinSmoothCosin ) - continue; + // vector<_LayerEdge*>& eE = eoe->_edges; + // for ( size_t iE = 0; iE < eE.size(); ++iE ) // loop on _LayerEdge's on EDGE or VERTEX + // { + // if ( eE[iE]->_cosin <= theMinSmoothCosin ) + // continue; - SMDS_ElemIteratorPtr segIt = eE[iE]->_nodes[0]->GetInverseElementIterator(SMDSAbs_Edge); - while ( segIt->more() ) - { - const SMDS_MeshElement* seg = segIt->next(); - if ( !eos->_subMesh->DependsOn( seg->getshapeId() )) - continue; - if ( seg->GetNode(0) != eE[iE]->_nodes[0] ) - continue; // not to check a seg twice - for ( size_t iN = 0; iN < eE[iE]->_neibors.size(); ++iN ) - { - _LayerEdge* eN = eE[iE]->_neibors[iN]; - if ( eN->_nodes[0]->getshapeId() != eos->_shapeID ) - continue; - double dist = SMESH_MeshAlgos::GetDistance( seg, SMESH_TNodeXYZ( eN->_nodes[0] )); - double smooLen = getSmoothingThickness( eE[iE]->_cosin, dist ); - eN->SetSmooLen( Min( smooLen, eN->GetSmooLen() )); - eN->Set( _LayerEdge::NEAR_BOUNDARY ); - } - } - } - } + // SMDS_ElemIteratorPtr segIt = eE[iE]->_nodes[0]->GetInverseElementIterator(SMDSAbs_Edge); + // while ( segIt->more() ) + // { + // const SMDS_MeshElement* seg = segIt->next(); + // if ( !eos->_subMesh->DependsOn( seg->getshapeId() )) + // continue; + // if ( seg->GetNode(0) != eE[iE]->_nodes[0] ) + // continue; // not to check a seg twice + // for ( size_t iN = 0; iN < eE[iE]->_neibors.size(); ++iN ) + // { + // _LayerEdge* eN = eE[iE]->_neibors[iN]; + // if ( eN->_nodes[0]->getshapeId() != eos->_shapeID ) + // continue; + // double dist = SMESH_MeshAlgos::GetDistance( seg, SMESH_TNodeXYZ( eN->_nodes[0] )); + // double smooLen = getSmoothingThickness( eE[iE]->_cosin, dist ); + // eN->SetSmooLen( Min( smooLen, eN->GetSmooLen() )); + // eN->Set( _LayerEdge::NEAR_BOUNDARY ); + // } + // } + // } + // } } // if ( eos->ShapeType() == TopAbs_FACE ) for ( size_t i = 0; i < eos->_edges.size(); ++i ) @@ -6420,6 +6499,7 @@ void _SolidData::PrepareEdgesToSmoothOnFace( _EdgesOnShape* eos, bool substitute avgLen /= edge->_simplices.size(); if (( edge->_curvature = _Curvature::New( avgNormProj, avgLen ))) { + edge->Set( _LayerEdge::SMOOTHED_C1 ); isCurved = true; SMDS_FacePosition* fPos = dynamic_cast( edge->_nodes[0]->GetPosition() ); if ( !fPos ) @@ -6515,7 +6595,7 @@ void _ViscousBuilder::limitMaxLenByCurvature( _SolidData& data, SMESH_MesherHelp if ( eI->_nodes[0]->GetID() < eN->_nodes[0]->GetID() ) // treat this pair once { _EdgesOnShape* eosN = data.GetShapeEdges( eN ); - limitMaxLenByCurvature( eI, eN, eosI, *eosN, helper ); + limitMaxLenByCurvature( eI, eN, eosI, *eosN, eosI._hyp.ToSmooth() ); } } } @@ -6529,7 +6609,7 @@ void _ViscousBuilder::limitMaxLenByCurvature( _SolidData& data, SMESH_MesherHelp for ( size_t i = 1; i < eosI._edges.size(); ++i ) { _LayerEdge* eI = eosI._edges[i]; - limitMaxLenByCurvature( eI, e0, eosI, eosI, helper ); + limitMaxLenByCurvature( eI, e0, eosI, eosI, eosI._hyp.ToSmooth() ); e0 = eI; } } @@ -6542,12 +6622,17 @@ void _ViscousBuilder::limitMaxLenByCurvature( _SolidData& data, SMESH_MesherHelp */ //================================================================================ -void _ViscousBuilder::limitMaxLenByCurvature( _LayerEdge* e1, - _LayerEdge* e2, - _EdgesOnShape& eos1, - _EdgesOnShape& eos2, - SMESH_MesherHelper& helper ) +void _ViscousBuilder::limitMaxLenByCurvature( _LayerEdge* e1, + _LayerEdge* e2, + _EdgesOnShape& eos1, + _EdgesOnShape& eos2, + const bool isSmoothable ) { + if (( e1->_nodes[0]->GetPosition()->GetDim() != + e2->_nodes[0]->GetPosition()->GetDim() ) && + ( e1->_cosin < 0.75 )) + return; // angle > 90 deg at e1 + gp_XYZ plnNorm = e1->_normal ^ e2->_normal; double norSize = plnNorm.SquareModulus(); if ( norSize < std::numeric_limits::min() ) @@ -6567,9 +6652,10 @@ void _ViscousBuilder::limitMaxLenByCurvature( _LayerEdge* e1, double ovl = ( u1 * e1->_normal * dir12 - u2 * e2->_normal * dir12 ) / dir12.SquareModulus(); if ( ovl > theSmoothThickToElemSizeRatio ) - { - e1->_maxLen = Min( e1->_maxLen, 0.75 * u1 / e1->_lenFactor ); - e2->_maxLen = Min( e2->_maxLen, 0.75 * u2 / e2->_lenFactor ); + { + const double coef = 0.75; + e1->SetMaxLen( Min( e1->_maxLen, coef * u1 / e1->_lenFactor )); + e2->SetMaxLen( Min( e2->_maxLen, coef * u2 / e2->_lenFactor )); } } } @@ -6744,7 +6830,7 @@ void _ViscousBuilder::findCollisionEdges( _SolidData& data, SMESH_MesherHelper& // else // { // double shortLen = 0.75 * ( Min( dist1, dist2 ) / edge->_lenFactor ); - // edge->_maxLen = Min( shortLen, edge->_maxLen ); + // edge->SetMaxLen( Min( shortLen, edge->_maxLen )); // } } @@ -6994,7 +7080,7 @@ bool _ViscousBuilder::updateNormals( _SolidData& data, e2neIt = edge2newEdge.insert( make_pair( edge1, zeroEdge )).first; e2neIt->second._normal += distWgt * newNormal; e2neIt->second._cosin = newCos; - e2neIt->second._maxLen = 0.7 * minIntDist / edge1->_lenFactor; + e2neIt->second.SetMaxLen( 0.7 * minIntDist / edge1->_lenFactor ); if ( iter > 0 && sgn1 * sgn2 < 0 && edge1->_cosin < 0 ) e2neIt->second._normal += dir2; @@ -7003,7 +7089,7 @@ bool _ViscousBuilder::updateNormals( _SolidData& data, if ( Precision::IsInfinite( zeroEdge._maxLen )) { e2neIt->second._cosin = edge2->_cosin; - e2neIt->second._maxLen = 1.3 * minIntDist / edge1->_lenFactor; + e2neIt->second.SetMaxLen( 1.3 * minIntDist / edge1->_lenFactor ); } if ( iter > 0 && sgn1 * sgn2 < 0 && edge2->_cosin < 0 ) e2neIt->second._normal += dir1; @@ -7033,7 +7119,7 @@ bool _ViscousBuilder::updateNormals( _SolidData& data, if ( newEdge._maxLen < edge->_len && iter > 0 ) // limit _maxLen { edge->InvalidateStep( stepNb + 1, *eos, /*restoreLength=*/true ); - edge->_maxLen = newEdge._maxLen; + edge->SetMaxLen( newEdge._maxLen ); edge->SetNewLength( newEdge._maxLen, *eos, helper ); } continue; // the new _normal is bad @@ -9454,9 +9540,9 @@ void _LayerEdge::Block( _SolidData& data ) SMESH_Comment msg( "#BLOCK shape="); msg << data.GetShapeEdges( this )->_shapeID << ", nodes " << _nodes[0]->GetID() << ", " << _nodes.back()->GetID(); - dumpCmd( msg + " -- BEGIN") + dumpCmd( msg + " -- BEGIN"); - _maxLen = _len; + SetMaxLen( _len ); std::queue<_LayerEdge*> queue; queue.push( this ); @@ -9480,18 +9566,19 @@ void _LayerEdge::Block( _SolidData& data ) double newMaxLen = edge->_maxLen + 0.5 * Sqrt( minDist ); //if ( edge->_nodes[0]->getshapeId() == neibor->_nodes[0]->getshapeId() ) viscous_layers_00/A3 { - newMaxLen *= edge->_lenFactor / neibor->_lenFactor; + //newMaxLen *= edge->_lenFactor / neibor->_lenFactor; // newMaxLen *= Min( edge->_lenFactor / neibor->_lenFactor, // neibor->_lenFactor / edge->_lenFactor ); } if ( neibor->_maxLen > newMaxLen ) { - neibor->_maxLen = newMaxLen; + neibor->SetMaxLen( newMaxLen ); if ( neibor->_maxLen < neibor->_len ) { _EdgesOnShape* eos = data.GetShapeEdges( neibor ); + int lastStep = neibor->Is( BLOCKED ) ? 1 : 0; while ( neibor->_len > neibor->_maxLen && - neibor->NbSteps() > 0 ) + neibor->NbSteps() > lastStep ) neibor->InvalidateStep( neibor->NbSteps(), *eos, /*restoreLength=*/true ); neibor->SetNewLength( neibor->_maxLen, *eos, data.GetHelper() ); //neibor->Block( data ); @@ -9500,7 +9587,7 @@ void _LayerEdge::Block( _SolidData& data ) } } } - dumpCmd( msg + " -- END") + dumpCmd( msg + " -- END"); } //================================================================================ @@ -9545,10 +9632,13 @@ void _LayerEdge::InvalidateStep( size_t curStep, const _EdgesOnShape& eos, bool { if ( NbSteps() == 0 ) _len = 0.; + else if ( IsOnFace() && Is( MOVED )) + _len = ( nXYZ.XYZ() - SMESH_NodeXYZ( _nodes[0] )) * _normal; else _len -= ( nXYZ.XYZ() - curXYZ ).Modulus() / _lenFactor; } } + return; } //================================================================================ @@ -9584,10 +9674,23 @@ void _LayerEdge::SmoothPos( const vector< double >& segLen, const double tol ) int iSmoothed = GetSmoothedPos( tol ); if ( !iSmoothed ) return; - //if ( 1 || Is( DISTORTED )) + gp_XYZ normal = _normal; + if ( Is( NORMAL_UPDATED )) { - gp_XYZ normal = _normal; - if ( Is( NORMAL_UPDATED )) + double minDot = 1; + for ( size_t i = 0; i < _neibors.size(); ++i ) + { + if ( _neibors[i]->IsOnFace() ) + { + double dot = _normal * _neibors[i]->_normal; + if ( dot < minDot ) + { + normal = _neibors[i]->_normal; + minDot = dot; + } + } + } + if ( minDot == 1. ) for ( size_t i = 1; i < _pos.size(); ++i ) { normal = _pos[i] - _pos[0]; @@ -9598,42 +9701,29 @@ void _LayerEdge::SmoothPos( const vector< double >& segLen, const double tol ) break; } } - const double r = 0.2; - for ( int iter = 0; iter < 50; ++iter ) - { - double minDot = 1; - for ( size_t i = Max( 1, iSmoothed-1-iter ); i < _pos.size()-1; ++i ) - { - gp_XYZ midPos = 0.5 * ( _pos[i-1] + _pos[i+1] ); - gp_XYZ newPos = ( 1-r ) * midPos + r * _pos[i]; - _pos[i] = newPos; - double midLen = 0.5 * ( segLen[i-1] + segLen[i+1] ); - double newLen = ( 1-r ) * midLen + r * segLen[i]; - const_cast< double& >( segLen[i] ) = newLen; - // check angle between normal and (_pos[i+1], _pos[i] ) - gp_XYZ posDir = _pos[i+1] - _pos[i]; - double size = posDir.SquareModulus(); - if ( size > RealSmall() ) - minDot = Min( minDot, ( normal * posDir ) * ( normal * posDir ) / size ); - } - if ( minDot > 0.5 * 0.5 ) - break; - } } - // else - // { - // for ( size_t i = 1; i < _pos.size()-1; ++i ) - // { - // if ((int) i < iSmoothed && ( segLen[i] / segLen.back() < 0.5 )) - // continue; - - // double wgt = segLen[i] / segLen.back(); - // gp_XYZ normPos = _pos[0] + _normal * wgt * _len; - // gp_XYZ tgtPos = ( 1 - wgt ) * _pos[0] + wgt * _pos.back(); - // gp_XYZ newPos = ( 1 - wgt ) * normPos + wgt * tgtPos; - // _pos[i] = newPos; - // } - // } + const double r = 0.2; + for ( int iter = 0; iter < 50; ++iter ) + { + double minDot = 1; + for ( size_t i = Max( 1, iSmoothed-1-iter ); i < _pos.size()-1; ++i ) + { + gp_XYZ midPos = 0.5 * ( _pos[i-1] + _pos[i+1] ); + gp_XYZ newPos = ( 1-r ) * midPos + r * _pos[i]; + _pos[i] = newPos; + double midLen = 0.5 * ( segLen[i-1] + segLen[i+1] ); + double newLen = ( 1-r ) * midLen + r * segLen[i]; + const_cast< double& >( segLen[i] ) = newLen; + // check angle between normal and (_pos[i+1], _pos[i] ) + gp_XYZ posDir = _pos[i+1] - _pos[i]; + double size = posDir.SquareModulus(); + if ( size > RealSmall() ) + minDot = Min( minDot, ( normal * posDir ) * ( normal * posDir ) / size ); + } + if ( minDot > 0.5 * 0.5 ) + break; + } + return; } //================================================================================ @@ -9674,11 +9764,11 @@ std::string _LayerEdge::DumpFlags() const return dump; } + //================================================================================ /*! - case brief: - default: -*/ + * \brief Create layers of prisms + */ //================================================================================ bool _ViscousBuilder::refine(_SolidData& data) @@ -9733,11 +9823,8 @@ bool _ViscousBuilder::refine(_SolidData& data) surface = helper.GetSurface( geomFace ); // propagate _toSmooth back to _eosC1, which was unset in findShapesToSmooth() for ( size_t i = 0; i < eos._eosC1.size(); ++i ) - { eos._eosC1[ i ]->_toSmooth = true; - for ( size_t j = 0; j < eos._eosC1[i]->_edges.size(); ++j ) - eos._eosC1[i]->_edges[j]->Set( _LayerEdge::SMOOTHED_C1 ); - } + isTooConvexFace = false; if ( _ConvexFace* cf = data.GetConvexFace( eos._shapeID )) isTooConvexFace = cf->_isTooCurved; @@ -11586,11 +11673,11 @@ bool _ViscousBuilder::addBoundaryElements(_SolidData& data) const SMDS_MeshNode* tgtN0 = ledges[0]->_nodes.back(); const SMDS_MeshNode* tgtN1 = ledges[1]->_nodes.back(); int nbSharedPyram = 0; - SMDS_ElemIteratorPtr vIt = tgtN0->GetInverseElementIterator(SMDSAbs_Volume); + SMDS_ElemIteratorPtr vIt = tgtN1->GetInverseElementIterator(SMDSAbs_Volume); while ( vIt->more() ) { const SMDS_MeshElement* v = vIt->next(); - nbSharedPyram += int( v->GetNodeIndex( tgtN1 ) >= 0 ); + nbSharedPyram += int( v->GetNodeIndex( tgtN0 ) >= 0 ); } if ( nbSharedPyram > 1 ) continue; // not free border of the pyramid diff --git a/src/StdMeshersGUI/StdMeshersGUI_DistrPreview.cxx b/src/StdMeshersGUI/StdMeshersGUI_DistrPreview.cxx index 7eb2f3348..f9ad75818 100644 --- a/src/StdMeshersGUI/StdMeshersGUI_DistrPreview.cxx +++ b/src/StdMeshersGUI/StdMeshersGUI_DistrPreview.cxx @@ -37,15 +37,8 @@ #include #include -#if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100 -#define NO_CAS_CATCH -#endif - #include - -#ifdef NO_CAS_CATCH #include -#endif #ifdef WIN32 # include @@ -356,12 +349,9 @@ void StdMeshersGUI_DistrPreview::update() x = y = 0; try { -#ifdef NO_CAS_CATCH OCC_CATCH_SIGNALS; -#endif replot(); } catch(Standard_Failure) { - Handle(Standard_Failure) aFail = Standard_Failure::Caught(); } } @@ -404,13 +394,10 @@ bool StdMeshersGUI_DistrPreview::init( const QString& str ) Kernel_Utils::Localizer loc; bool parsed_ok = true; try { -#ifdef NO_CAS_CATCH OCC_CATCH_SIGNALS; -#endif myExpr = ExprIntrp_GenExp::Create(); myExpr->Process( ( Standard_CString ) str.toLatin1().data() ); } catch(Standard_Failure) { - Handle(Standard_Failure) aFail = Standard_Failure::Caught(); parsed_ok = false; } @@ -446,12 +433,9 @@ double StdMeshersGUI_DistrPreview::calc( bool& ok ) ok = true; try { -#ifdef NO_CAS_CATCH OCC_CATCH_SIGNALS; -#endif res = myExpr->Expression()->Evaluate( myVars, myValues ); } catch(Standard_Failure) { - Handle(Standard_Failure) aFail = Standard_Failure::Caught(); ok = false; res = 0.0; } @@ -472,16 +456,13 @@ bool StdMeshersGUI_DistrPreview::convert( double& v ) const case EXPONENT: { try { -#ifdef NO_CAS_CATCH OCC_CATCH_SIGNALS; -#endif // in StdMeshers_NumberOfSegments.cc // const double PRECISION = 1e-7; // if(v < -7) v = -7.0; v = pow( 10.0, v ); } catch(Standard_Failure) { - Handle(Standard_Failure) aFail = Standard_Failure::Caught(); v = 0.0; ok = false; } diff --git a/src/StdMeshersGUI/StdMeshers_msg_en.ts b/src/StdMeshersGUI/StdMeshers_msg_en.ts index 5b6fe40c3..91a1b3ca6 100644 --- a/src/StdMeshersGUI/StdMeshers_msg_en.ts +++ b/src/StdMeshersGUI/StdMeshers_msg_en.ts @@ -136,7 +136,7 @@ this one for this mesh/sub-mesh. SMESH_DISTR_EXPR - Distribution with analitic density + Distribution with analytic density SMESH_DISTR_REGULAR diff --git a/src/Tools/MGCleanerPlug/CMakeLists.txt b/src/Tools/MGCleanerPlug/CMakeLists.txt index 50a2d05c9..71758729d 100644 --- a/src/Tools/MGCleanerPlug/CMakeLists.txt +++ b/src/Tools/MGCleanerPlug/CMakeLists.txt @@ -16,36 +16,41 @@ # # See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com # + IF(SALOME_BUILD_DOC) ADD_SUBDIRECTORY(doc) ENDIF(SALOME_BUILD_DOC) -INCLUDE(UsePyQt) +IF(SALOME_BUILD_GUI) + INCLUDE(UsePyQt) +ENDIF(SALOME_BUILD_GUI) # --- scripts --- # scripts / static -SET(plugin_SCRIPTS +SET(_plugin_SCRIPTS MGCleanerMonPlugDialog.py MGCleanerMonViewText.py MGCleanerplug_plugin.py ) -# --- resources --- - -# uic files / to be processed by pyuic -SET(_pyuic_files - MGCleanerPlugDialog.ui - MGCleanerViewText.ui -) - -# scripts / pyuic wrappings -PYQT_WRAP_UIC(_pyuic_SCRIPTS ${_pyuic_files}) +IF(SALOME_BUILD_GUI) + # uic files / to be processed by pyuic + SET(_pyuic_FILES + MGCleanerPlugDialog.ui + MGCleanerViewText.ui + ) + # scripts / pyuic wrappings + PYQT_WRAP_UIC(_pyuic_SCRIPTS ${_pyuic_FILES} TARGET_NAME _target_name_pyuic) +ENDIF(SALOME_BUILD_GUI) # --- rules --- -SALOME_INSTALL_SCRIPTS("${plugin_SCRIPTS}" ${SALOME_SMESH_INSTALL_PLUGINS}) +SALOME_INSTALL_SCRIPTS("${_plugin_SCRIPTS}" ${SALOME_SMESH_INSTALL_PLUGINS}) IF(SALOME_BUILD_GUI) - SALOME_INSTALL_SCRIPTS("${_pyuic_SCRIPTS}" ${SALOME_SMESH_INSTALL_PLUGINS}) -ENDIF(SALOME_BUILD_GUI) \ No newline at end of file + SALOME_INSTALL_SCRIPTS("${_pyuic_SCRIPTS}" ${SALOME_SMESH_INSTALL_PLUGINS} TARGET_NAME _target_name_pyuic_py) + # add dependency of compiled py files on uic files in order + # to avoid races problems when compiling in parallel + ADD_DEPENDENCIES(${_target_name_pyuic_py} ${_target_name_pyuic}) +ENDIF(SALOME_BUILD_GUI) diff --git a/src/Tools/MacMesh/MacMesh/MacObject.py b/src/Tools/MacMesh/MacMesh/MacObject.py index 162c7d5b7..c541fd949 100644 --- a/src/Tools/MacMesh/MacMesh/MacObject.py +++ b/src/Tools/MacMesh/MacMesh/MacObject.py @@ -241,7 +241,7 @@ class MacObject: import GenFunctions, Config from salome.geom import geomBuilder - geompy = geomBuilder.New( Config.theStudy ) + geompy = geomBuilder.New() if isinstance(Criterion, str) : Crit = {'South' : lambda : 0, diff --git a/src/Tools/MacMesh/MacMesh/PublishGroups.py b/src/Tools/MacMesh/MacMesh/PublishGroups.py index 172d632d0..7b768d84f 100644 --- a/src/Tools/MacMesh/MacMesh/PublishGroups.py +++ b/src/Tools/MacMesh/MacMesh/PublishGroups.py @@ -96,146 +96,146 @@ def Publish (ObjToPublish): for i,GeoObj in enumerate(ObjToPublish) : geompy.addToStudy(GeoObj,"Sub_"+str(i)) def RevolveMesh(MainMesh,**args): - """ - This function premits to revolute and scale a 2D mesh while transforming the edge - groups into face groups. Moreover, the function automatically creates the face groups - corresponding to the symmetry lower and upper faces - Facultatif arguments are : - - Center [X,Y,Z], origin being the default - - Direction [VX,VY,VZ], x-axis being the default - - AngleDeg or AngleRad : ALPHA, 10 degrees being the default - - Scale : BETA, no scaling being default - """ - ################################################################################ - # Reading input arguments and proceeding to defaults if necessary - ################################################################################ - if 'Center' in args : CenterCoor = [float(Coor) for Coor in args['Center']] - else : - print("\nThe coordinates of the center of revolution were not given\nThe origin is used by default.") - CenterCoor = [0.,0.,0.] + """ + This function permits to revolute and scale a 2D mesh while transforming the edge + groups into face groups. Moreover, the function automatically creates the face groups + corresponding to the symmetry lower and upper faces + Facultatif arguments are : + - Center [X,Y,Z], origin being the default + - Direction [VX,VY,VZ], x-axis being the default + - AngleDeg or AngleRad : ALPHA, 10 degrees being the default + - Scale : BETA, no scaling being default + """ + ################################################################################ + # Reading input arguments and proceeding to defaults if necessary + ################################################################################ + if 'Center' in args : CenterCoor = [float(Coor) for Coor in args['Center']] + else : + print("\nThe coordinates of the center of revolution were not given\nThe origin is used by default.") + CenterCoor = [0.,0.,0.] + + if 'Direction' in args : Direction = [float(Dir) for Dir in args['Direction']] + else : + print("\nThe axis vector of revolution was not given\nThe x-axis is used by default.") + Direction = [1.,0.,0.] + + if 'AngleDeg' in args : Angle = float(args['AngleDeg'])*math.pi/180. + elif 'AngleRad' in args : Angle = float(args['AngleRad']) + else : + print("\nThe revolution angle was not given\nAn angle of 10 degrees is used by default.") + Angle = 10.*math.pi/180. + + if 'Scale' in args : Scale = float(args['Scale']) + else : Scale = 1. + - if 'Direction' in args : Direction = [float(Dir) for Dir in args['Direction']] - else : - print("\nThe axis vector of revolution was not given\nThe x-axis is used by default.") - Direction = [1.,0.,0.] + # Creating the lower face group LOFAC + LOFAC = MainMesh.CreateEmptyGroup( SMESH.FACE, 'LOFAC' ) + LOFAC.AddFrom(MainMesh.GetMesh()) - if 'AngleDeg' in args : Angle = float(args['AngleDeg'])*math.pi/180. - elif 'AngleRad' in args : Angle = float(args['AngleRad']) - else : - print("\nThe revolution angle was not given\nAn angle of 10 degrees is used by default.") - Angle = 10.*math.pi/180. + GR_Names = MainMesh.GetGroupNames() + GRs = MainMesh.GetGroups() + Rev3DMeshGroups = MainMesh.RotationSweepObject2D( MainMesh, SMESH.AxisStruct( CenterCoor[0], CenterCoor[1], CenterCoor[2], Direction[0], Direction[1], Direction[2] ), Angle, 1, 1e-05 ,True) - if 'Scale' in args : Scale = float(args['Scale']) - else : Scale = 1. + # Adding an EDGE suffix to the edge groups (to be deleted eventually by the user...) + for GR in GRs: + CurrentName = GR.GetName() + if CurrentName in GR_Names and not(CurrentName=='LOFAC'): # Meaning that this is an old edge group + GR.SetName(CurrentName+'_EDGE') + # Removing the _rotated prefix from the rotated FACE groups + for GR in Rev3DMeshGroups: + CurrentName = GR.GetName() + if CurrentName.endswith( "_rotated"): + if CurrentName.startswith( 'LOFAC_' ): + GR.SetName('VOL') + else: + GR.SetName(CurrentName[:-8]) + elif CurrentName == 'LOFAC_top': + GR.SetName('HIFAC') + #Index = [ GR_Names[i] in CurrentName for i in range(0,len(GR_Names)) ].index(True) + #GR.SetName(GR_Names[Index]) - # Creating the lower face group LOFAC - LOFAC = MainMesh.CreateEmptyGroup( SMESH.FACE, 'LOFAC' ) - LOFAC.AddFrom(MainMesh.GetMesh()) - - GR_Names = MainMesh.GetGroupNames() - GRs = MainMesh.GetGroups() - Rev3DMeshGroups = MainMesh.RotationSweepObject2D( MainMesh, SMESH.AxisStruct( CenterCoor[0], CenterCoor[1], CenterCoor[2], Direction[0], Direction[1], Direction[2] ), Angle, 1, 1e-05 ,True) - - # Adding an EDGE suffix to the edge groups (to be deleted eventually by the user...) - for GR in GRs: - CurrentName = GR.GetName() - if CurrentName in GR_Names and not(CurrentName=='LOFAC'): # Meaning that this is an old edge group - GR.SetName(CurrentName+'_EDGE') - - # Removing the _rotated prefix from the rotated FACE groups - for GR in Rev3DMeshGroups: - CurrentName = GR.GetName() - if CurrentName.endswith( "_rotated"): - if CurrentName.startswith( 'LOFAC_' ): - GR.SetName('VOL') - else: - GR.SetName(CurrentName[:-8]) - elif CurrentName == 'LOFAC_top': - GR.SetName('HIFAC') - #Index = [ GR_Names[i] in CurrentName for i in range(0,len(GR_Names)) ].index(True) - #GR.SetName(GR_Names[Index]) - - # Creating the upper face group HIFAC - ALLFAC = MainMesh.CreateEmptyGroup( SMESH.FACE, 'ALLFAC' ) - ALLFAC.AddFrom(MainMesh.GetMesh()) - - #HIFAC = MainMesh.GetMesh().CutListOfGroups( [ ALLFAC ], [LOFAC] + [ MeshGroup for MeshGroup in Rev3DMeshGroups if not(MeshGroup.GetName()=='VOL') ], 'HIFAC' ) - #HIFAC = MainMesh.GetMesh().CutListOfGroups( [ ALLFAC ], [LOFAC] + [ MeshGroup for MeshGroup in Rev3DMeshGroups if ( not(MeshGroup.GetName()=='VOL') and MeshGroup.GetType() == SMESH.FACE )], 'HIFAC' ) - - # Scaling down the mesh to meter units - if not(Scale==1.): - MeshEditor = MainMesh.GetMeshEditor() - MeshEditor.Scale( MainMesh.GetMesh(), SMESH.PointStruct( 0, 0, 0 ) ,[ Scale, Scale, Scale ], 0 ) + # Creating the upper face group HIFAC + ALLFAC = MainMesh.CreateEmptyGroup( SMESH.FACE, 'ALLFAC' ) + ALLFAC.AddFrom(MainMesh.GetMesh()) + #HIFAC = MainMesh.GetMesh().CutListOfGroups( [ ALLFAC ], [LOFAC] + [ MeshGroup for MeshGroup in Rev3DMeshGroups if not(MeshGroup.GetName()=='VOL') ], 'HIFAC' ) + #HIFAC = MainMesh.GetMesh().CutListOfGroups( [ ALLFAC ], [LOFAC] + [ MeshGroup for MeshGroup in Rev3DMeshGroups if ( not(MeshGroup.GetName()=='VOL') and MeshGroup.GetType() == SMESH.FACE )], 'HIFAC' ) + # Scaling down the mesh to meter units + if not(Scale==1.): + MeshEditor = MainMesh.GetMeshEditor() + MeshEditor.Scale( MainMesh.GetMesh(), SMESH.PointStruct( 0, 0, 0 ) ,[ Scale, Scale, Scale ], 0 ) + + def ExtrudeMesh(MainMesh,**args): - """ - This function premits to extrude and scale a 2D mesh while transforming the edge - groups into face groups. Moreover, the function automatically creates the face groups - corresponding to the symmetry lower and upper faces - Facultatif arguments are : - - Direction [VX,VY,VZ], z-axis being default - - Distance : D, default is 1 - - NSteps : the object will be extruded by NSteps*Distance, default is Nsteps = 1 - - Scale : BETA, no scaling being default - """ - ################################################################################ - # Reading input arguments and proceeding to defaults if necessary - ################################################################################ - if 'Distance' in args : Distance = float(args['Distance']) - else : - print("\nThe extrusion distance was not given\nA default value of 1 is used.") - Distance = 1. + """ + This function permits to extrude and scale a 2D mesh while transforming the edge + groups into face groups. Moreover, the function automatically creates the face groups + corresponding to the symmetry lower and upper faces + Facultatif arguments are : + - Direction [VX,VY,VZ], z-axis being default + - Distance : D, default is 1 + - NSteps : the object will be extruded by NSteps*Distance, default is Nsteps = 1 + - Scale : BETA, no scaling being default + """ + ################################################################################ + # Reading input arguments and proceeding to defaults if necessary + ################################################################################ + if 'Distance' in args : Distance = float(args['Distance']) + else : + print("\nThe extrusion distance was not given\nA default value of 1 is used.") + Distance = 1. + + if 'Direction' in args : Direction = NormalizeVector([float(Dir) for Dir in args['Direction']],Distance) + else : + print("\nThe extrusion vector of revolution was not given\nThe z-axis is used by default.") + Direction = NormalizeVector([0.,0.,1.],Distance) + + if 'Scale' in args : Scale = float(args['Scale']) + else : Scale = 1. + + if 'NSteps' in args : NSteps = int(args['NSteps']) + else : NSteps = 1 + + # Creating the lower face group LOFAC + LOFAC = MainMesh.CreateEmptyGroup( SMESH.FACE, 'LOFAC' ) + LOFAC.AddFrom(MainMesh.GetMesh()) - if 'Direction' in args : Direction = NormalizeVector([float(Dir) for Dir in args['Direction']],Distance) - else : - print("\nThe extrusion vector of revolution was not given\nThe z-axis is used by default.") - Direction = NormalizeVector([0.,0.,1.],Distance) + GR_Names = MainMesh.GetGroupNames() + GRs = MainMesh.GetGroups() + Ext3DMeshGroups = MainMesh.ExtrusionSweepObject2D(MainMesh,SMESH.DirStruct(SMESH.PointStruct(Direction[0],Direction[1],Direction[2])), NSteps, True) - if 'Scale' in args : Scale = float(args['Scale']) - else : Scale = 1. + # Adding an EDGE suffix to the edge groups (to be deleted eventually by the user...) + for GR in GRs: + CurrentName = GR.GetName() + if CurrentName in GR_Names and not(CurrentName=='LOFAC'): # Meaning that this is an old edge group + GR.SetName(CurrentName+'_EDGE') - if 'NSteps' in args : NSteps = int(args['NSteps']) - else : NSteps = 1 + # Removing the _extruded suffix from the extruded FACE groups + for GR in Ext3DMeshGroups: + CurrentName = GR.GetName() + if CurrentName.endswith( "_extruded"): + if CurrentName.startswith( 'LOFAC_' ): + GR.SetName('VOL') + else: + GR.SetName(CurrentName[:-9]) + elif CurrentName == 'LOFAC_top': + GR.SetName('HIFAC') - # Creating the lower face group LOFAC - LOFAC = MainMesh.CreateEmptyGroup( SMESH.FACE, 'LOFAC' ) - LOFAC.AddFrom(MainMesh.GetMesh()) - - GR_Names = MainMesh.GetGroupNames() - GRs = MainMesh.GetGroups() - Ext3DMeshGroups = MainMesh.ExtrusionSweepObject2D(MainMesh,SMESH.DirStruct(SMESH.PointStruct(Direction[0],Direction[1],Direction[2])), NSteps, True) - - # Adding an EDGE suffix to the edge groups (to be deleted eventually by the user...) - for GR in GRs: - CurrentName = GR.GetName() - if CurrentName in GR_Names and not(CurrentName=='LOFAC'): # Meaning that this is an old edge group - GR.SetName(CurrentName+'_EDGE') - - # Removing the _extruded suffix from the extruded FACE groups - for GR in Ext3DMeshGroups: - CurrentName = GR.GetName() - if CurrentName.endswith( "_extruded"): - if CurrentName.startswith( 'LOFAC_' ): - GR.SetName('VOL') - else: - GR.SetName(CurrentName[:-9]) - elif CurrentName == 'LOFAC_top': - GR.SetName('HIFAC') - - # Creating the upper face group HIFAC - ALLFAC = MainMesh.CreateEmptyGroup( SMESH.FACE, 'ALLFAC' ) - ALLFAC.AddFrom(MainMesh.GetMesh()) - - #HIFAC = MainMesh.GetMesh().CutListOfGroups( [ ALLFAC ], [LOFAC] + [ MeshGroup for MeshGroup in Ext3DMeshGroups if not(MeshGroup.GetName()=='VOL') ], 'HIFAC' ) - - # Scaling down the mesh to meter units - if not(Scale==1.): - MeshEditor = MainMesh.GetMeshEditor() - MeshEditor.Scale( MainMesh.GetMesh(), SMESH.PointStruct( 0, 0, 0 ) ,[ Scale, Scale, Scale ], 0 ) + # Creating the upper face group HIFAC + ALLFAC = MainMesh.CreateEmptyGroup( SMESH.FACE, 'ALLFAC' ) + ALLFAC.AddFrom(MainMesh.GetMesh()) + #HIFAC = MainMesh.GetMesh().CutListOfGroups( [ ALLFAC ], [LOFAC] + [ MeshGroup for MeshGroup in Ext3DMeshGroups if not(MeshGroup.GetName()=='VOL') ], 'HIFAC' ) + # Scaling down the mesh to meter units + if not(Scale==1.): + MeshEditor = MainMesh.GetMeshEditor() + MeshEditor.Scale( MainMesh.GetMesh(), SMESH.PointStruct( 0, 0, 0 ) ,[ Scale, Scale, Scale ], 0 ) + + def NormalizeVector (V,Norm): """ This function returns a normalized vector (magnitude = Norm), parallel to the entered one diff --git a/src/Tools/MeshCut/CMakeLists.txt b/src/Tools/MeshCut/CMakeLists.txt index 2125c0be1..44c8cae1c 100644 --- a/src/Tools/MeshCut/CMakeLists.txt +++ b/src/Tools/MeshCut/CMakeLists.txt @@ -38,7 +38,7 @@ SET(_link_LIBRARIES # --- scripts --- # scripts / static -SET(plugin_SCRIPTS +SET(_plugin_SCRIPTS meshcut_plugin.py ) @@ -61,26 +61,25 @@ SET(MeshCut_SOURCES ) IF(SALOME_BUILD_GUI) - # --- resources --- - # uic files / to be processed by pyuic - SET(_pyuic_files + SET(_pyuic_FILES MeshCutDialog.ui ) - # scripts / pyuic wrappings - PYQT_WRAP_UIC(_pyuic_SCRIPTS ${_pyuic_files}) - + PYQT_WRAP_UIC(_pyuic_SCRIPTS ${_pyuic_FILES} TARGET_NAME _target_name_pyuic) ENDIF(SALOME_BUILD_GUI) # --- rules --- -SALOME_INSTALL_SCRIPTS("${plugin_SCRIPTS}" ${SALOME_SMESH_INSTALL_PLUGINS}) +SALOME_INSTALL_SCRIPTS("${_plugin_SCRIPTS}" ${SALOME_SMESH_INSTALL_PLUGINS}) ADD_EXECUTABLE(MeshCut ${MeshCut_SOURCES}) TARGET_LINK_LIBRARIES(MeshCut ${_link_LIBRARIES}) INSTALL(TARGETS MeshCut EXPORT ${PROJECT_NAME}TargetGroup DESTINATION ${SALOME_INSTALL_BINS}) IF(SALOME_BUILD_GUI) - INSTALL(FILES ${_pyuic_SCRIPTS} DESTINATION ${SALOME_INSTALL_BINS}) + SALOME_INSTALL_SCRIPTS("${_pyuic_SCRIPTS}" ${SALOME_INSTALL_BINS} TARGET_NAME _target_name_pyuic_py) + # add dependency of compiled py files on uic files in order + # to avoid races problems when compiling in parallel + ADD_DEPENDENCIES(${_target_name_pyuic_py} ${_target_name_pyuic}) ENDIF(SALOME_BUILD_GUI) diff --git a/src/Tools/MeshCut/MeshCut_Maillage.cxx b/src/Tools/MeshCut/MeshCut_Maillage.cxx index de5a5b036..ed48c6717 100644 --- a/src/Tools/MeshCut/MeshCut_Maillage.cxx +++ b/src/Tools/MeshCut/MeshCut_Maillage.cxx @@ -324,7 +324,7 @@ void Maillage::inputMED(std::string fichierMED) // Lecture des infos concernant le premier maillage if (MEDmeshInfo(fid, 1, maa, &spacedim, &mdim, &type, desc, dtunit, &sortingtype, &nPasTemps, &axistype, axisname, unitname) < 0) - ERREUR("Error while reading mesh informations "); + ERREUR("Error while reading mesh information "); //cout << chrono() << " --- inputMED: MEDmeshInfo: OK" << endl; // cerr << "maa=" << maa << endl; diff --git a/src/Tools/Verima/Gui/CMakeLists.txt b/src/Tools/Verima/Gui/CMakeLists.txt index 07c0275a1..1e0cf7b74 100644 --- a/src/Tools/Verima/Gui/CMakeLists.txt +++ b/src/Tools/Verima/Gui/CMakeLists.txt @@ -22,7 +22,7 @@ INCLUDE(UsePyQt) # --- scripts --- # scripts / static -SET(plugin_SCRIPTS +SET(_plugin_SCRIPTS maFenetreChoix.py monEditor.py monNomBase.py @@ -30,10 +30,8 @@ SET(plugin_SCRIPTS __init__.py ) -# --- resources --- - # uic files / to be processed by pyuic -SET(_pyuic_files +SET(_pyuic_FILES desFenetreChoix.ui desStat.ui myMainTotale.ui @@ -42,12 +40,14 @@ SET(_pyuic_files nomBase.ui tousLesJobs.ui ) - # scripts / pyuic wrappings -PYQT_WRAP_UIC(_pyuic_SCRIPTS ${_pyuic_files}) +PYQT_WRAP_UIC(_pyuic_SCRIPTS ${_pyuic_FILES} TARGET_NAME _target_name_pyuic) # --- rules --- -SALOME_INSTALL_SCRIPTS("${plugin_SCRIPTS}" ${SALOME_SMESH_INSTALL_PLUGINS}/Verima/Gui) +SALOME_INSTALL_SCRIPTS("${_plugin_SCRIPTS}" ${SALOME_SMESH_INSTALL_PLUGINS}/Verima/Gui) -SALOME_INSTALL_SCRIPTS("${_pyuic_SCRIPTS}" ${SALOME_SMESH_INSTALL_PLUGINS}/Verima/Gui) +SALOME_INSTALL_SCRIPTS("${_pyuic_SCRIPTS}" ${SALOME_SMESH_INSTALL_PLUGINS}/Verima/Gui TARGET_NAME _target_name_pyuic_py) +# add dependency of compiled py files on uic files in order +# to avoid races problems when compiling in parallel +ADD_DEPENDENCIES(${_target_name_pyuic_py} ${_target_name_pyuic}) diff --git a/src/Tools/Verima/Stats/Type_Maille.py b/src/Tools/Verima/Stats/Type_Maille.py index 7fc73a3b5..3185f4d63 100644 --- a/src/Tools/Verima/Stats/Type_Maille.py +++ b/src/Tools/Verima/Stats/Type_Maille.py @@ -20,6 +20,7 @@ dicoDimENtite= { 'Entity_Node':0, 'Entity_Quad_Pyramid':1, 'Entity_Penta ':1, 'Entity_Quad_Penta':1, +'Entity_BiQuad_Penta':1, 'Entity_Hexagonal_Prism':1, 'Entity_Polyhedra':1, 'Entity_Quad_Polyhedra':1, diff --git a/src/Tools/YamsPlug/CMakeLists.txt b/src/Tools/YamsPlug/CMakeLists.txt index 29e6fc99f..9ab185c11 100644 --- a/src/Tools/YamsPlug/CMakeLists.txt +++ b/src/Tools/YamsPlug/CMakeLists.txt @@ -21,30 +21,36 @@ IF(SALOME_BUILD_DOC) ADD_SUBDIRECTORY(doc) ENDIF(SALOME_BUILD_DOC) -INCLUDE(UsePyQt) +IF(SALOME_BUILD_GUI) + INCLUDE(UsePyQt) +ENDIF(SALOME_BUILD_GUI) # --- scripts --- # scripts / static -SET(plugin_SCRIPTS +SET(_plugin_SCRIPTS monYamsPlugDialog.py monViewText.py yamsplug_plugin.py ) -# --- resources --- - -# uic files / to be processed by pyuic -SET(_pyuic_files - YamsPlugDialog.ui - ViewText.ui -) - -# scripts / pyuic wrappings -PYQT_WRAP_UIC(_pyuic_SCRIPTS ${_pyuic_files}) +IF(SALOME_BUILD_GUI) + # uic files / to be processed by pyuic + SET(_pyuic_FILES + YamsPlugDialog.ui + ViewText.ui + ) + # scripts / pyuic wrappings + PYQT_WRAP_UIC(_pyuic_SCRIPTS ${_pyuic_FILES} TARGET_NAME _target_name_pyuic) +ENDIF(SALOME_BUILD_GUI) # --- rules --- -SALOME_INSTALL_SCRIPTS("${plugin_SCRIPTS}" ${SALOME_SMESH_INSTALL_PLUGINS}) +SALOME_INSTALL_SCRIPTS("${_plugin_SCRIPTS}" ${SALOME_SMESH_INSTALL_PLUGINS}) -SALOME_INSTALL_SCRIPTS("${_pyuic_SCRIPTS}" ${SALOME_SMESH_INSTALL_PLUGINS}) \ No newline at end of file +IF(SALOME_BUILD_GUI) + SALOME_INSTALL_SCRIPTS("${_pyuic_SCRIPTS}" ${SALOME_SMESH_INSTALL_PLUGINS} TARGET_NAME _target_name_pyuic_py) + # add dependency of compiled py files on uic files in order + # to avoid races problems when compiling in parallel + ADD_DEPENDENCIES(${_target_name_pyuic_py} ${_target_name_pyuic}) +ENDIF(SALOME_BUILD_GUI) diff --git a/src/Tools/YamsPlug/doc/Advanced_params.rst b/src/Tools/YamsPlug/doc/Advanced_params.rst index 23b0385bd..e0034905b 100644 --- a/src/Tools/YamsPlug/doc/Advanced_params.rst +++ b/src/Tools/YamsPlug/doc/Advanced_params.rst @@ -8,7 +8,7 @@ Advanced Remeshing Options - **Ridge detection** if not set (ridge detection disabled ), MeshGems-SurfOpt will not try to detect any new ridge edge by its own mechanism : -it will consider as ridge only the ridges given in the mesh. All non-ridge edges that would have been detected as ridge by the Ridge angle paramaeter (see below split edge) will be considered as part of the same continuous patch. This option should not be checked when all the known ridges of the mesh are given and when all other possible ridges are not geometric ridges to take into account. +it will consider as ridge only the ridges given in the mesh. All non-ridge edges that would have been detected as ridge by the Ridge angle parameter (see below split edge) will be considered as part of the same continuous patch. This option should not be checked when all the known ridges of the mesh are given and when all other possible ridges are not geometric ridges to take into account. - **Point smoothing** When not set (point smoothing is disabled), MeshGems-SurfOpt will not try to move the initial given vertices (along an edge, a ridge or onto the surface), hence MeshGems-SurfOpt will only swap edges, remove vertices or add vertices (refines) to change the mesh. @@ -34,8 +34,8 @@ These two parameters allow the user to prescribe a Maximal/Minimal size for the - **Mesh gradation** -This paramater P controls the element size variation : MeshGems-SurfOpt will avoid having two adjacent egdes which sizes vary more than th given gradation. a size correction is applied to the size map : if two adjacent edges are respectively e1 and e2 long and e2 > Pxe1, then, the new size for the second edge will be set to P x e1. -**This procedure is desactived if P=-1** +This parameter P controls the element size variation : MeshGems-SurfOpt will avoid having two adjacent egdes which sizes vary more than th given gradation. A size correction is applied to the size map : if two adjacent edges are respectively e1 and e2 long and e2 > Pxe1, then, the new size for the second edge will be set to P x e1. +**This procedure is deactived if P=-1** diff --git a/src/Tools/YamsPlug/doc/Generics_params.rst b/src/Tools/YamsPlug/doc/Generics_params.rst index a38e68289..29453af2e 100644 --- a/src/Tools/YamsPlug/doc/Generics_params.rst +++ b/src/Tools/YamsPlug/doc/Generics_params.rst @@ -15,7 +15,7 @@ You usually don't have to set this parameter but you can choose to limit the amo - **File** -You can change the file used to store remeshing hypotheses, see :ref:`hypothesis-label` for further informations. +You can change the file used to store remeshing hypotheses, see :ref:`hypothesis-label` for further information. .. image:: images/Generic.png :align: center diff --git a/src/Tools/YamsPlug/doc/Mandatory_params.rst b/src/Tools/YamsPlug/doc/Mandatory_params.rst index d4aff8f19..8d9cf5560 100644 --- a/src/Tools/YamsPlug/doc/Mandatory_params.rst +++ b/src/Tools/YamsPlug/doc/Mandatory_params.rst @@ -98,7 +98,7 @@ it can be : - relative : the maximal chordal deviation - epsilon max - is set to *s x the parameter* where *s* is the size of the bounding box longest diagonal. By default, the parameter is set to 0.001 and the maximum deviation is then set to 0.001 x s, - which is equivalent to say that, for a bouding box of 1 meter, the maximal deviation is 1 mm. + which is equivalent to say that, for a bounding box of 1 meter, the maximal deviation is 1 mm. - absolute : the maximal chordal deviation is the parameter itself. eg if the parameter equals 2, the maximal chordal deviation will be 2 (mm if the point coordonates are given in mm). Following that criterion: diff --git a/src/Tools/ZCracksPlug/CMakeLists.txt b/src/Tools/ZCracksPlug/CMakeLists.txt index cc77ad1a7..9ab6df413 100644 --- a/src/Tools/ZCracksPlug/CMakeLists.txt +++ b/src/Tools/ZCracksPlug/CMakeLists.txt @@ -19,12 +19,14 @@ ADD_SUBDIRECTORY(casTests) -INCLUDE(UsePyQt) +IF(SALOME_BUILD_GUI) + INCLUDE(UsePyQt) +ENDIF(SALOME_BUILD_GUI) # --- scripts --- # scripts / static -SET(plugin_SCRIPTS +SET(_plugin_SCRIPTS __init__.py ellipse.py genereCrack.py @@ -37,29 +39,35 @@ SET(plugin_SCRIPTS Zset.py ) -SET(command_SCRIPTS +SET(_command_SCRIPTS zcracksLaunch.py ) -# --- resources --- - -# uic files / to be processed by pyuic -SET(_pyuic_files - zcracks.ui -) +IF(SALOME_BUILD_GUI) + # uic files / to be processed by pyuic + SET(_pyuic_FILES + zcracks.ui + ) # qrc files / to be processed by pyrcc -SET(_pyqrcc_files +SET(_pyqrc_FILES images.qrc ) -# scripts / pyuic wrappings -PYQT_WRAP_UIC(_pyuic_SCRIPTS ${_pyuic_files} OPTIONS "--import-from=Zcracks" "--resource-suffix=_qrc") -PYQT_WRAP_QRC(_pyqrc_SCRIPTS ${_pyqrcc_files}) + # scripts / pyuic wrappings + PYQT_WRAP_UIC(_pyuic_SCRIPTS ${_pyuic_FILES} TARGET_NAME _target_name_pyuic OPTIONS "--import-from=Zcracks" "--resource-suffix=_qrc") + PYQT_WRAP_QRC(_pyqrc_SCRIPTS ${_pyqrc_FILES}) +ENDIF(SALOME_BUILD_GUI) # --- rules --- -SALOME_INSTALL_SCRIPTS("${plugin_SCRIPTS}" ${SALOME_INSTALL_PYTHON}/Zcracks) -SALOME_INSTALL_SCRIPTS("${_pyuic_SCRIPTS}" ${SALOME_INSTALL_PYTHON}/Zcracks) -SALOME_INSTALL_SCRIPTS("${_pyqrc_SCRIPTS}" ${SALOME_INSTALL_PYTHON}/Zcracks) -SALOME_INSTALL_SCRIPTS("${command_SCRIPTS}" ${SALOME_INSTALL_BINS}) +SALOME_INSTALL_SCRIPTS("${_plugin_SCRIPTS}" ${SALOME_INSTALL_PYTHON}/Zcracks) +SALOME_INSTALL_SCRIPTS("${_command_SCRIPTS}" ${SALOME_INSTALL_BINS}) +IF(SALOME_BUILD_GUI) + SALOME_INSTALL_SCRIPTS("${_pyuic_SCRIPTS}" ${SALOME_INSTALL_PYTHON}/Zcracks TARGET_NAME _target_name_pyuic_py) + SALOME_INSTALL_SCRIPTS("${_pyqrc_SCRIPTS}" ${SALOME_INSTALL_PYTHON}/Zcracks) + # add dependency of compiled py files on uic files in order + # to avoid races problems when compiling in parallel + ADD_DEPENDENCIES(${_target_name_pyuic_py} ${_target_name_pyuic}) +ENDIF(SALOME_BUILD_GUI) + diff --git a/src/Tools/ZCracksPlug/casTests/genereCube.py b/src/Tools/ZCracksPlug/casTests/genereCube.py index b26bc63ac..94ff1c0be 100644 --- a/src/Tools/ZCracksPlug/casTests/genereCube.py +++ b/src/Tools/ZCracksPlug/casTests/genereCube.py @@ -7,10 +7,9 @@ import salome salome.salome_init() -theStudy = salome.myStudy import salome_notebook -notebook = salome_notebook.NoteBook(theStudy) +notebook = salome_notebook.NoteBook() ### ### GEOM component @@ -25,7 +24,7 @@ def cube3D(L, N, outFile): N=int(N) from salome.geom import geomBuilder - geompy = geomBuilder.New(theStudy) + geompy = geomBuilder.New() eps=L*1.e-6 @@ -69,7 +68,7 @@ def cube3D(L, N, outFile): from salome.smesh import smeshBuilder import SMESH - smesh = smeshBuilder.New(theStudy) + smesh = smeshBuilder.New() Nb_Segments_1 = smesh.CreateHypothesis('NumberOfSegments') Nb_Segments_1.SetNumberOfSegments( N ) Length_From_Edges_1 = smesh.CreateHypothesis('LengthFromEdges') @@ -112,7 +111,7 @@ def cube3D(L, N, outFile): Maillage_1.ExportMED(outFile) #if salome.sg.hasDesktop(): - #salome.sg.updateObjBrowser(True) + #salome.sg.updateObjBrowser() @@ -121,7 +120,7 @@ def cube2D(L, N, outFile): N=int(N) from salome.geom import geomBuilder - geompy = geomBuilder.New(theStudy) + geompy = geomBuilder.New() eps=L*1.e-6 @@ -156,7 +155,7 @@ def cube2D(L, N, outFile): from salome.smesh import smeshBuilder import SMESH - smesh = smeshBuilder.New(theStudy) + smesh = smeshBuilder.New() Nb_Segments_1 = smesh.CreateHypothesis('NumberOfSegments') Nb_Segments_1.SetNumberOfSegments( N ) Length_From_Edges_1 = smesh.CreateHypothesis('LengthFromEdges') @@ -194,4 +193,4 @@ def cube2D(L, N, outFile): Maillage_1.ExportMED(outFile) #if salome.sg.hasDesktop(): - #salome.sg.updateObjBrowser(True) + #salome.sg.updateObjBrowser() diff --git a/src/Tools/ZCracksPlug/ellipse.py b/src/Tools/ZCracksPlug/ellipse.py index 9f599892a..4aa93106e 100644 --- a/src/Tools/ZCracksPlug/ellipse.py +++ b/src/Tools/ZCracksPlug/ellipse.py @@ -9,10 +9,9 @@ import sys, numpy import salome salome.salome_init() -theStudy = salome.myStudy import salome_notebook -notebook = salome_notebook.NoteBook(theStudy) +notebook = salome_notebook.NoteBook() ### ### GEOM component @@ -45,7 +44,7 @@ def generate(data_demi_grand_axe, data_centre, data_normale, Vnormale, Vdirection, Vortho = uF.calcCoordVectors(data_normale, data_direction) Vcentre = numpy.array(data_centre) - geompy = geomBuilder.New(theStudy) + geompy = geomBuilder.New() O = geompy.MakeVertex(0, 0, 0) OX = geompy.MakeVectorDXDYDZ(1, 0, 0) @@ -172,7 +171,7 @@ def generate(data_demi_grand_axe, data_centre, data_normale, import SMESH, SALOMEDS from salome.smesh import smeshBuilder - smesh = smeshBuilder.New(theStudy) + smesh = smeshBuilder.New() A=numpy.pi/(30.) minAxes=numpy.min([data_demi_grand_axe,data_demi_petit_axe]) @@ -199,4 +198,4 @@ def generate(data_demi_grand_axe, data_centre, data_normale, if salome.sg.hasDesktop(): - salome.sg.updateObjBrowser(True) + salome.sg.updateObjBrowser() diff --git a/src/Tools/ZCracksPlug/genereCrack.py b/src/Tools/ZCracksPlug/genereCrack.py index 1628cd465..ebec86ad4 100644 --- a/src/Tools/ZCracksPlug/genereCrack.py +++ b/src/Tools/ZCracksPlug/genereCrack.py @@ -212,13 +212,12 @@ def generateCustom(crack, outFile): import salome salome.salome_init() - theStudy = salome.myStudy import salome_notebook - notebook = salome_notebook.NoteBook(theStudy) + notebook = salome_notebook.NoteBook() import SMESH, SALOMEDS from salome.smesh import smeshBuilder - smesh = smeshBuilder.New(theStudy) + smesh = smeshBuilder.New() ([Maillage_1], status) = smesh.CreateMeshesFromMED(crack['med file']) isCrack=False for group in Maillage_1.GetGroups(): diff --git a/src/Tools/ZCracksPlug/main.py b/src/Tools/ZCracksPlug/main.py index fb75c82e1..ecc73966b 100644 --- a/src/Tools/ZCracksPlug/main.py +++ b/src/Tools/ZCracksPlug/main.py @@ -431,9 +431,8 @@ class ShipHolderApplication(QGroupBox): else: import SMESH, salome #salome.salome_init() - theStudy = salome.myStudy from salome.smesh import smeshBuilder - smesh = smeshBuilder.New(theStudy) + smesh = smeshBuilder.New() ([objetSain], status) = smesh.CreateMeshesFromMED(saneFile) diff --git a/src/Tools/ZCracksPlug/rectangle.py b/src/Tools/ZCracksPlug/rectangle.py index f885150eb..6a6e15f9d 100644 --- a/src/Tools/ZCracksPlug/rectangle.py +++ b/src/Tools/ZCracksPlug/rectangle.py @@ -8,10 +8,9 @@ import sys, numpy import salome salome.salome_init() -theStudy = salome.myStudy import salome_notebook -notebook = salome_notebook.NoteBook(theStudy) +notebook = salome_notebook.NoteBook() ### ### GEOM component @@ -65,7 +64,7 @@ def generate(data_longueur,data_largeur,data_centre, Vnormale, Vdirection, Vortho = uF.calcCoordVectors(data_normale, data_direction) Vcentre = numpy.array(data_centre) - geompy = geomBuilder.New(theStudy) + geompy = geomBuilder.New() O = geompy.MakeVertex(0, 0, 0) OX = geompy.MakeVectorDXDYDZ(1, 0, 0) @@ -211,7 +210,7 @@ def generate(data_longueur,data_largeur,data_centre, import SMESH, SALOMEDS from salome.smesh import smeshBuilder - smesh = smeshBuilder.New(theStudy) + smesh = smeshBuilder.New() Maillage=uF.meshCrack(FACE_FISSURE, minSize, maxSize, chordal, dim) @@ -223,4 +222,4 @@ def generate(data_longueur,data_largeur,data_centre, if salome.sg.hasDesktop(): - salome.sg.updateObjBrowser(True) + salome.sg.updateObjBrowser() diff --git a/src/Tools/ZCracksPlug/sphere.py b/src/Tools/ZCracksPlug/sphere.py index 04e75bb74..4ea4ea8cb 100644 --- a/src/Tools/ZCracksPlug/sphere.py +++ b/src/Tools/ZCracksPlug/sphere.py @@ -8,10 +8,9 @@ import sys, numpy import salome salome.salome_init() -theStudy = salome.myStudy import salome_notebook -notebook = salome_notebook.NoteBook(theStudy) +notebook = salome_notebook.NoteBook() ### ### GEOM component @@ -30,7 +29,7 @@ def generate(data_rayon,data_centre,outFile): #data_rayon = 0.1 #data_centre = [1., 1., 01.] - geompy = geomBuilder.New(theStudy) + geompy = geomBuilder.New() O = geompy.MakeVertex(0, 0, 0) OX = geompy.MakeVectorDXDYDZ(1, 0, 0) @@ -48,7 +47,7 @@ def generate(data_rayon,data_centre,outFile): import SMESH, SALOMEDS from salome.smesh import smeshBuilder - smesh = smeshBuilder.New(theStudy) + smesh = smeshBuilder.New() A=numpy.pi/(20.) chordal, minSize = uF.calcElemSize(A, data_rayon) @@ -67,4 +66,4 @@ def generate(data_rayon,data_centre,outFile): if salome.sg.hasDesktop(): - salome.sg.updateObjBrowser(True) + salome.sg.updateObjBrowser() diff --git a/src/Tools/ZCracksPlug/utilityFunctions.py b/src/Tools/ZCracksPlug/utilityFunctions.py index 0acde8671..e7aab2a28 100644 --- a/src/Tools/ZCracksPlug/utilityFunctions.py +++ b/src/Tools/ZCracksPlug/utilityFunctions.py @@ -131,11 +131,10 @@ def meshCrack(geomObject, minSize, maxSize, chordal, dim): import salome salome.salome_init() - theStudy = salome.myStudy import SMESH, SALOMEDS from salome.smesh import smeshBuilder - smesh = smeshBuilder.New(theStudy) + smesh = smeshBuilder.New() Maillage = smesh.Mesh(geomObject) if dim==3: @@ -173,9 +172,8 @@ def extendElsets(meshFile, outFile=None): import SMESH, salome #salome.salome_init() - theStudy = salome.myStudy from salome.smesh import smeshBuilder - smesh = smeshBuilder.New(theStudy) + smesh = smeshBuilder.New() ([mesh], status) = smesh.CreateMeshesFromMED(meshFile) diff --git a/src/Tools/ZCracksPlug/zcracks.ui b/src/Tools/ZCracksPlug/zcracks.ui index 8fc299d22..3de4be60e 100644 --- a/src/Tools/ZCracksPlug/zcracks.ui +++ b/src/Tools/ZCracksPlug/zcracks.ui @@ -567,7 +567,7 @@ - Extraction length (optionnal) + Extraction length (optional) Extraction length diff --git a/src/Tools/blocFissure/ihm/CMakeLists.txt b/src/Tools/blocFissure/ihm/CMakeLists.txt index 64e0b3a18..1d24db51d 100644 --- a/src/Tools/blocFissure/ihm/CMakeLists.txt +++ b/src/Tools/blocFissure/ihm/CMakeLists.txt @@ -22,7 +22,7 @@ INCLUDE(UsePyQt) # --- scripts --- # scripts / static -SET(plugin_SCRIPTS +SET(_plugin_SCRIPTS __init__.py fissureCoude_ihm.py fissureCoude_plugin.py @@ -30,19 +30,19 @@ SET(plugin_SCRIPTS dialogFissureCoude.dic ) -# --- resources --- - # uic files / to be processed by pyuic -SET(_pyuic_files +SET(_pyuic_FILES fissureCoude.ui fissureGenerale.ui ) - # scripts / pyuic wrappings -PYQT_WRAP_UIC(_pyuic_SCRIPTS ${_pyuic_files} OPTIONS "--import-from=blocFissure" "--resource-suffix=_qrc") +PYQT_WRAP_UIC(_pyuic_SCRIPTS ${_pyuic_FILES} TARGET_NAME _target_name_pyuic OPTIONS "--import-from=blocFissure" "--resource-suffix=_qrc") # --- rules --- -SALOME_INSTALL_SCRIPTS("${plugin_SCRIPTS}" ${SALOME_INSTALL_PYTHON}/blocFissure/ihm) +SALOME_INSTALL_SCRIPTS("${_plugin_SCRIPTS}" ${SALOME_INSTALL_PYTHON}/blocFissure/ihm) -SALOME_INSTALL_SCRIPTS("${_pyuic_SCRIPTS}" ${SALOME_INSTALL_PYTHON}/blocFissure/ihm) +SALOME_INSTALL_SCRIPTS("${_pyuic_SCRIPTS}" ${SALOME_INSTALL_PYTHON}/blocFissure/ihm TARGET_NAME _target_name_pyuic_py) +# add dependency of compiled py files on uic files in order +# to avoid races problems when compiling in parallel +ADD_DEPENDENCIES(${_target_name_pyuic_py} ${_target_name_pyuic}) diff --git a/src/Tools/blocFissure/materielCasTests/decoupeCylindre.py b/src/Tools/blocFissure/materielCasTests/decoupeCylindre.py index b5fe06e21..8e0077695 100644 --- a/src/Tools/blocFissure/materielCasTests/decoupeCylindre.py +++ b/src/Tools/blocFissure/materielCasTests/decoupeCylindre.py @@ -4,7 +4,6 @@ import sys import salome salome.salome_init() -theStudy = salome.myStudy import salome_notebook notebook = salome_notebook.notebook @@ -149,8 +148,8 @@ SubMesh_1 = Regular_1D_1.GetSubMesh() SubMesh_2 = Regular_1D_2.GetSubMesh() ## some objects were removed -aStudyBuilder = theStudy.NewBuilder() -SO = theStudy.FindObjectIOR(theStudy.ConvertObjectToIOR(smeshObj_1)) +aStudyBuilder = salome.myStudy.NewBuilder() +SO = salome.myStudy.FindObjectIOR(salome.myStudy.ConvertObjectToIOR(smeshObj_1)) if SO is not None: aStudyBuilder.RemoveObjectWithChildren(SO) ## set object names smesh.SetName(CylindreSain_1.GetMesh(), 'CylindreSain') diff --git a/src/Tools/padder/meshjob/impl/MeshJobManager_i.cxx b/src/Tools/padder/meshjob/impl/MeshJobManager_i.cxx index 7a77330d8..a4ba0446d 100644 --- a/src/Tools/padder/meshjob/impl/MeshJobManager_i.cxx +++ b/src/Tools/padder/meshjob/impl/MeshJobManager_i.cxx @@ -371,7 +371,7 @@ CORBA::Long MeshJobManager_i::initialize(const MESHJOB::MeshJobFileList & meshJo // Specification of the working spaces: // // - local_directory: can be used to specify where to find the input - // files on the local resource. It's optionnal if you specify the + // files on the local resource. It's optional if you specify the // absolute path name of input files. // // - result_directory: must be used to specify where to download the @@ -429,7 +429,7 @@ CORBA::Long MeshJobManager_i::initialize(const MESHJOB::MeshJobFileList & meshJo //jobParameters->maximum_duration = CORBA::string_dup("01:00"); jobParameters->queue = CORBA::string_dup(""); - // Setting resource and additionnal properties (if needed) + // Setting resource and additional properties (if needed) // The resource parameters can be initiated from scratch, for // example by specifying the values in hard coding: // >>> @@ -451,7 +451,7 @@ CORBA::Long MeshJobManager_i::initialize(const MESHJOB::MeshJobFileList & meshJo resourceDefinition = _resourcesManager->GetResourceDefinition(resourceName); } catch (const CORBA::SystemException& ex) { - _lastErrorMessage = std::string("We can not access to the ressource ") + std::string(resourceName); + _lastErrorMessage = std::string("We can not access the resource ") + std::string(resourceName); _lastErrorMessage+= std::string("(check the file CatalogResource.xml)"); LOG(_lastErrorMessage); return JOBID_UNDEFINED; @@ -462,7 +462,7 @@ CORBA::Long MeshJobManager_i::initialize(const MESHJOB::MeshJobFileList & meshJo // Then, the values can be used to initiate the resource parameters // of the job: jobParameters->resource_required.name = CORBA::string_dup(resourceDefinition->name.in()); - // CAUTION: the additionnal two following parameters MUST be + // CAUTION: the additional two following parameters MUST be // specified explicitly, because they are not provided by the // resource definition: jobParameters->resource_required.mem_mb = resourceDefinition->mem_mb; @@ -682,7 +682,7 @@ std::vector * MeshJobManager_i::_getResourceNames() { // SALOME application. // In the code instructions, you just have to choose a resource // configuration by its name and then define the ResourceParameters - // that specify additionnal properties for a specific job submission + // that specify additional properties for a specific job submission // (use the attribute resource_required of the JobParameters). return resourceNames; diff --git a/src/Tools/padder/meshjob/impl/MeshJobManager_i.hxx b/src/Tools/padder/meshjob/impl/MeshJobManager_i.hxx index 618a4a2f2..177c4ccfa 100644 --- a/src/Tools/padder/meshjob/impl/MeshJobManager_i.hxx +++ b/src/Tools/padder/meshjob/impl/MeshJobManager_i.hxx @@ -73,7 +73,7 @@ private: Engines::ResourcesManager_var _resourcesManager; // This maps the config identifier to the config parameters. A - // config is a resource with additionnal data specifying the + // config is a resource with additional data specifying the // location of the binary program to be executed by the task std::map _configMap; diff --git a/src/Tools/padder/spadderpy/gui/CMakeLists.txt b/src/Tools/padder/spadderpy/gui/CMakeLists.txt index 8bffecdc7..3ee6b8567 100644 --- a/src/Tools/padder/spadderpy/gui/CMakeLists.txt +++ b/src/Tools/padder/spadderpy/gui/CMakeLists.txt @@ -22,7 +22,7 @@ INCLUDE(UsePyQt) # --- scripts --- # scripts / static -SET(py_SCRIPTS +SET(_py_SCRIPTS __init__.py plugindialog.py inputdialog.py @@ -32,7 +32,7 @@ SET(py_SCRIPTS # --- resources --- # uic files / to be processed by pyuic -SET(spadderpy_DATA +SET(_spadderpy_DATA parameters.png input.png select.png @@ -46,15 +46,20 @@ SET(spadderpy_DATA steelbar.png ) -SET(_pyuic_files +SET(_pyuic_FILES plugindialog.ui inputframe.ui ) # scripts / pyuic wrappings -PYQT_WRAP_UIC(_pyuic_SCRIPTS ${_pyuic_files}) +PYQT_WRAP_UIC(_pyuic_SCRIPTS ${_pyuic_FILES} TARGET_NAME _target_name_pyuic) # --- rules --- -SALOME_INSTALL_SCRIPTS("${_pyuic_SCRIPTS}" ${SALOME_INSTALL_PYTHON}/salome/smesh/spadder/gui) -SALOME_INSTALL_SCRIPTS("${py_SCRIPTS}" ${SALOME_INSTALL_PYTHON}/salome/smesh/spadder/gui) -INSTALL(FILES ${spadderpy_DATA} DESTINATION ${SALOME_INSTALL_PYTHON}/salome/smesh/spadder/gui) +SALOME_INSTALL_SCRIPTS("${_pyuic_SCRIPTS}" ${SALOME_INSTALL_PYTHON}/salome/smesh/spadder/gui TARGET_NAME _target_name_pyuic_py) +# add dependency of compiled py files on uic files in order +# to avoid races problems when compiling in parallel +ADD_DEPENDENCIES(${_target_name_pyuic_py} ${_target_name_pyuic}) + +SALOME_INSTALL_SCRIPTS("${_py_SCRIPTS}" ${SALOME_INSTALL_PYTHON}/salome/smesh/spadder/gui) + +INSTALL(FILES ${_spadderpy_DATA} DESTINATION ${SALOME_INSTALL_PYTHON}/salome/smesh/spadder/gui)