From: eap Date: Fri, 27 Mar 2015 16:41:20 +0000 (+0300) Subject: 22874: [CEA 1425] Performance SMESH Module X-Git-Tag: V7_6_0a1~4 X-Git-Url: http://git.salome-platform.org/gitweb/?p=modules%2Fsmesh.git;a=commitdiff_plain;h=0921263864977d53ebb778e3d1c9d88d61a4912f 22874: [CEA 1425] Performance SMESH Module Fix a leak of PropagationMgrData + Do not use volumes for preview of Extrusion + Fix a regression: empty groups are not removed with contents + avoid too long waiting at creation of hypotheses due to use of GEOMUtils::PreciseBoundingBox() in SMESH_Mesh::GetShapeDiagonalSize() --- diff --git a/doc/salome/gui/SMESH/images/quad_mesh_invalid.png b/doc/salome/gui/SMESH/images/quad_mesh_invalid.png new file mode 100644 index 000000000..cce9980f5 Binary files /dev/null and b/doc/salome/gui/SMESH/images/quad_mesh_invalid.png differ diff --git a/doc/salome/gui/SMESH/images/quad_meshes.png b/doc/salome/gui/SMESH/images/quad_meshes.png new file mode 100644 index 000000000..c6cbd0c7a Binary files /dev/null and b/doc/salome/gui/SMESH/images/quad_meshes.png differ diff --git a/doc/salome/gui/SMESH/input/about_hypo.doc b/doc/salome/gui/SMESH/input/about_hypo.doc index 3c38fb7db..b2dab5dbf 100644 --- a/doc/salome/gui/SMESH/input/about_hypo.doc +++ b/doc/salome/gui/SMESH/input/about_hypo.doc @@ -10,6 +10,22 @@ with different parameters you can preset the quantity or size of elements which will compose your mesh. So, it will be possible to generate a coarse or a more refined mesh. +The choice of a hypothesis depends on the selected algorithm. + +Hypotheses are created during creation and edition of +\ref constructing_meshes_page "meshes" and +\ref constructing_submeshes_page "sub-mesh". +Once created a hypotheses can be reused during creation and +edition of other meshes and sub-meshes. All created hypotheses and +algorithms are present in the Object Browser in \a Hypotheses and +\a Algorithms folders correspondingly. From the context menu of the +hypothesis you can invoke a dialog for modification of its parameters, +and \b Unassign command that will unassign the hypothesis from all +the meshes and sub-meshes using it. +Modification of any hypothesis parameter and unassignment of a +hypothesis leads to automatic removal of elements generated with use +of this hypothesis. + In \b MESH there are the following Basic Hypotheses: There also exist -\subpage additional_hypo_page "Additional Hypotheses" that can be used together -with main hypotheses: +\subpage additional_hypo_page "Additional Hypotheses": -The choice of a hypothesis depends on the selected algorithm. - */ diff --git a/doc/salome/gui/SMESH/input/about_meshes.doc b/doc/salome/gui/SMESH/input/about_meshes.doc index 60ad290a8..470cb854d 100644 --- a/doc/salome/gui/SMESH/input/about_meshes.doc +++ b/doc/salome/gui/SMESH/input/about_meshes.doc @@ -18,7 +18,7 @@ Mesh module provides several ways to create the mesh: objects). Construction of \subpage constructing_submeshes_page "sub-meshes" - allows to mesh some sub-shapes of the main shape, for example a face, + allows to discretize some sub-shapes of the main shape, for example a face, using different meshing parameters than other sub-shapes.
Meshing parameters of meshes and sub-meshes can be \subpage editing_meshes_page "edited". (Upon edition only mesh entities @@ -58,6 +58,12 @@ Mesh module provides several ways to create the mesh: Meshes can be edited using the MESH functions destined for \ref modifying_meshes_page "modification" of meshes. +Attractive meshing capabilities include: +- 3D and 2D \ref viscous_layers_anchor "Viscous Layers" (boundary + layers of highly stretched elements beneficial for high quality + viscous computations); +- automatic conformal transition between tetrahedral and hexahedral + sub-meshes. The \b structure of a SALOME mesh is described by nodes and elements based on these nodes. Geometry of the element is defined by the sequence of diff --git a/doc/salome/gui/SMESH/input/basic_meshing_algos.doc b/doc/salome/gui/SMESH/input/basic_meshing_algos.doc index bdf730b67..f494926d1 100644 --- a/doc/salome/gui/SMESH/input/basic_meshing_algos.doc +++ b/doc/salome/gui/SMESH/input/basic_meshing_algos.doc @@ -28,8 +28,8 @@ number of mesh segments following an 1D hypothesis. \image html image123.gif "Example of a triangular 2D mesh" diff --git a/doc/salome/gui/SMESH/input/constructing_submeshes.doc b/doc/salome/gui/SMESH/input/constructing_submeshes.doc index 8e750f6a2..9da2e4f7f 100644 --- a/doc/salome/gui/SMESH/input/constructing_submeshes.doc +++ b/doc/salome/gui/SMESH/input/constructing_submeshes.doc @@ -89,13 +89,15 @@ The following dialog box will appear: \par \image html createmesh-inv2.png -\par It allows to define the \b Name, the parent \b Mesh and the \b Geometry (e.g. a face if the parent mesh has been built on box) of the sub-mesh. You can define meshing algorithms and hypotheses in the same way as -in \ref constructing_meshes_page "Create mesh" dialog. +in \ref constructing_meshes_page "Create mesh" dialog. + +Later you can change applied hypotheses or their parameters in +\ref editing_meshes_page "Edit mesh/sub-mesh" dialog. Mesh entities +generated using changed hypotheses are automatically removed. -\par \anchor subshape_by_mesh_elem If the parent mesh is already computed, then you can define the \b Geometry by picking mesh elements computed on a sub-shape of interest @@ -106,18 +108,14 @@ already down, then click it to release and then click it again. The following pop-up menu allowing to choose a way of geometry definition will appear. -\par \image html choose_geom_selection_way.png -\par Direct geometry selection enables selecting the sub-shape in the Object Browser. Find geometry by mesh element selection activates the following dialog. -\par \image html find_geom_by_mesh_elem.png -\par In this dialog, Element Type defines a kind of element to pick in the Viewer. Instead of picking an element in the Viewer, you can type its @@ -126,22 +124,20 @@ ID in Element ID field. with which the sub-shape will appear in the Object Browser (if not yet there). -\par In the Object Browser the structure of the new sub-mesh will be displayed as follows: \image html image10.jpg -\par It contains:
See Also a sample TUI Script of a diff --git a/doc/salome/gui/SMESH/input/editing_meshes.doc b/doc/salome/gui/SMESH/input/editing_meshes.doc index 4cc70553f..a4602e6c4 100644 --- a/doc/salome/gui/SMESH/input/editing_meshes.doc +++ b/doc/salome/gui/SMESH/input/editing_meshes.doc @@ -16,10 +16,13 @@ You can also change values for the current hypothesis by clicking the \image html image122.png
"Edit Hypothesis" button
+Mesh entities generated before using changed hypotheses are automatically removed. + See how the mesh constructed on a geometrical object -changes if we apply different algorithms to it. +changes if we apply different meshing parameters to it. \image html edit_mesh1.png "Example of a mesh with Max. Element area 2D hypothesis roughly corresponding to 1D hypotheses on edges" +
\image html edit_mesh_change_value_hyp.png "And now the Max Element area is greatly reduced" diff --git a/doc/salome/gui/SMESH/input/quad_ijk_algo.doc b/doc/salome/gui/SMESH/input/quad_ijk_algo.doc new file mode 100644 index 000000000..dfdb2d5cb --- /dev/null +++ b/doc/salome/gui/SMESH/input/quad_ijk_algo.doc @@ -0,0 +1,49 @@ +/*! + +\page quad_ijk_algo_page Quadrangle (Mapping) meshing algorithm + +Quadrangle (Mapping) meshing algorithm is intended for creating +all-quadrangle and quad-dominant meshes on faces with no holes and +bound by at least three edges. + +The algorithm can create mesh on any face but mesh quality and +validity depends on two factors: +- face shape (number of edges and concavity of boundary); +- discretization of edges. + +\image html quad_mesh_invalid.png "Invalid mesh on quadrilateral concave faces" + +The algorithm uses Transfinite Interpolation technic in +parametric space of a face to locate nodes inside the face. + +The algorithm treats any face as a quadrangle. If a face is bound by +more than four edges, four most sharp vertices are considered as +corners of the quadrangle and all edges between these vertices are +treated as quadrangle sides. In the case of three edges, the vertex +specified by the user is considered as a degenerated side of the +quadrangle. + +\image html quad_meshes.png "Algorithm generates a structured mesh on complex faces provided that edges are properly discretized" + +To get an all-quadrangle mesh you have to carefully define 1D +hypotheses on edges of a face. To get a \b structured mesh you have to assure +equal number of segments on opposite sides of the quadrangle. If this +condition is not respected, the algorithm by default (with no +hypothesis) creates \b quad-dominant mesh with triangles located near a +side with maximal number of segments. But you can get an +\b all-quadrangle mesh in this case by using +\ref hypo_quad_params_anchor "Quadrangle Parameters" +hypothesis to specify how to make transition mesh between opposite +sides with different number of segments, provided that certain +conditions are respected. In any case total number of segments must be +even. To use \a Reduced transition method there must be equal number +of segments on one pair of opposite sides. + +The following hypotheses help in creation of quadrangle meshes. +- \ref propagation_anchor "Propagation" additional 1D hypotheses + help to get equal number of segments on opposite sides of the + quadrilateral face. +- \ref a1d_algos_anchor "Composite Side Discretization" algorithm is useful + to discretize several C1 continues edges as one quadrangle side. + +*/ diff --git a/src/SMESH/SMESH_Mesh.cxx b/src/SMESH/SMESH_Mesh.cxx index 20deb04a6..992e31735 100644 --- a/src/SMESH/SMESH_Mesh.cxx +++ b/src/SMESH/SMESH_Mesh.cxx @@ -58,7 +58,7 @@ #include #undef _Precision_HeaderFile -//#include +#include #include #include #include @@ -72,11 +72,12 @@ #include "SMESH_TryCatch.hxx" // include after OCCT headers! #include "Utils_ExceptHandlers.hxx" + #ifndef WIN32 #include #include #else -#include +include #endif using namespace std; @@ -180,6 +181,23 @@ SMESH_Mesh::~SMESH_Mesh() { MESSAGE("SMESH_Mesh::~SMESH_Mesh"); + // Unassign algorithms in order to have all SMESH_subMeshEventListenerData deleted (22874) + SMESHDS_SubMeshIteratorPtr smIt = _myMeshDS->SubMeshes(); + while ( smIt->more() ) { + // avoid usual removal of elements while processing RemoveHypothesis( algo ) event + const_cast( smIt->next() )->Clear(); + } + const ShapeToHypothesis & hyps = _myMeshDS->GetHypotheses(); + for ( ShapeToHypothesis::Iterator s2hyps( hyps ); s2hyps.More(); s2hyps.Next() ) + { + const TopoDS_Shape& s = s2hyps.Key(); + THypList hyps = s2hyps.ChangeValue(); // copy + THypList::const_iterator h = hyps.begin(); + for ( ; h != hyps.end(); ++h ) + if ( (*h)->GetType() != SMESHDS_Hypothesis::PARAM_ALGO ) + RemoveHypothesis( s, (*h)->GetID() ); + } + // issue 0020340: EDF 1022 SMESH : Crash with FindNodeClosestTo in a second new study // Notify event listeners at least that something happens if ( SMESH_subMesh * sm = GetSubMeshContaining(1)) @@ -329,7 +347,16 @@ double SMESH_Mesh::GetShapeDiagonalSize(const TopoDS_Shape & aShape) { if ( !aShape.IsNull() ) { Bnd_Box Box; - GEOMUtils::PreciseBoundingBox(aShape, Box); + // avoid too long waiting on large shapes. PreciseBoundingBox() was added + // to assure same result which else depends on presence of triangulation (IPAL52557). + const int maxNbFaces = 4000; + int nbFaces = 0; + for ( TopExp_Explorer f( aShape, TopAbs_FACE ); f.More() && nbFaces < maxNbFaces; f.Next() ) + ++nbFaces; + if ( nbFaces < maxNbFaces ) + GEOMUtils::PreciseBoundingBox(aShape, Box); + else + BRepBndLib::Add( aShape, Box); if ( !Box.IsVoid() ) return sqrt( Box.SquareExtent() ); } diff --git a/src/SMESH_I/SMESH_Gen_i.cxx b/src/SMESH_I/SMESH_Gen_i.cxx index 715d6656a..468352968 100644 --- a/src/SMESH_I/SMESH_Gen_i.cxx +++ b/src/SMESH_I/SMESH_Gen_i.cxx @@ -747,7 +747,7 @@ SMESH_Gen_i::GetHypothesisParameterValues (const char* theHypType, return SMESH::SMESH_Hypothesis::_nil(); ::SMESH_Mesh* mesh = meshServant ? &meshServant->GetImpl() : (::SMESH_Mesh*)0; - // create a temporary hypothesis to know its dimention + // create a temporary hypothesis to know its dimension SMESH::SMESH_Hypothesis_var tmpHyp = this->createHypothesis( theHypType, theLibName ); SMESH_Hypothesis_i* hypServant = SMESH::DownCast( tmpHyp ); if ( !hypServant ) @@ -2427,6 +2427,7 @@ SMESH_Gen_i::ConcatenateCommon(const SMESH::ListOfIDSources& theMeshesArray, // loop on sub-meshes for ( int i = 0; i < theMeshesArray.length(); i++) { + if ( CORBA::is_nil( theMeshesArray[i] )) continue; SMESH::SMESH_Mesh_var anInitMesh = theMeshesArray[i]->GetMesh(); if ( anInitMesh->_is_nil() ) continue; SMESH_Mesh_i* anInitImpl = SMESH::DownCast( anInitMesh ); diff --git a/src/SMESH_I/SMESH_MeshEditor_i.cxx b/src/SMESH_I/SMESH_MeshEditor_i.cxx index d233bb63f..519478d30 100644 --- a/src/SMESH_I/SMESH_MeshEditor_i.cxx +++ b/src/SMESH_I/SMESH_MeshEditor_i.cxx @@ -182,6 +182,12 @@ namespace MeshEditor_I { { GetMeshDS()->ClearMesh(); } + void Remove( SMDSAbs_ElementType type ) + { + SMDS_ElemIteratorPtr eIt = GetMeshDS()->elementsIterator( type ); + while ( eIt->more() ) + GetMeshDS()->RemoveFreeElement( eIt->next(), /*sm=*/0, /*fromGroups=*/false ); + } };// struct TPreviewMesh static SMESH_NodeSearcher * theNodeSearcher = 0; @@ -2398,6 +2404,10 @@ SMESH_MeshEditor_i::RotationSweepObjects(const SMESH::ListOfIDSources & theNodes << TVar( theTolerance ) << ", " << theMakeGroups << " )"; } + else + { + getPreviewMesh()->Remove( SMDSAbs_Volume ); + } return aGroups ? aGroups : new SMESH::ListOfGroups; @@ -2551,6 +2561,10 @@ SMESH_MeshEditor_i::ExtrusionSweepObjects(const SMESH::ListOfIDSources & theNode << TVar( theNbOfSteps ) << ", " << theToMakeGroups << " )"; } + else + { + getPreviewMesh()->Remove( SMDSAbs_Volume ); + } return aGroups ? aGroups : new SMESH::ListOfGroups; @@ -2623,6 +2637,10 @@ SMESH_MeshEditor_i::ExtrusionByNormal(const SMESH::ListOfIDSources& objects, << ", " << dim << " )"; } + else + { + getPreviewMesh()->Remove( SMDSAbs_Volume ); + } declareMeshModified( /*isReComputeSafe=*/true ); // does not influence Compute() @@ -2675,6 +2693,10 @@ SMESH_MeshEditor_i::AdvancedExtrusion(const SMESH::long_array & theIDsOfElements << theSewTolerance << ", " << theMakeGroups << " )"; } + else + { + getPreviewMesh()->Remove( SMDSAbs_Volume ); + } return aGroups ? aGroups : new SMESH::ListOfGroups; @@ -2844,6 +2866,10 @@ SMESH_MeshEditor_i::ExtrusionAlongPathObjects(const SMESH::ListOfIDSources & the << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ), " << theMakeGroups << " )"; } + else + { + getPreviewMesh()->Remove( SMDSAbs_Volume ); + } return aGroups._retn(); diff --git a/src/SMESH_I/SMESH_Mesh_i.cxx b/src/SMESH_I/SMESH_Mesh_i.cxx index cc209d379..7649c27de 100644 --- a/src/SMESH_I/SMESH_Mesh_i.cxx +++ b/src/SMESH_I/SMESH_Mesh_i.cxx @@ -105,7 +105,7 @@ int SMESH_Mesh_i::_idGenerator = 0; SMESH_Mesh_i::SMESH_Mesh_i( PortableServer::POA_ptr thePOA, SMESH_Gen_i* gen_i, - CORBA::Long studyId ) + CORBA::Long studyId ) : SALOME::GenericObj_i( thePOA ) { MESSAGE("SMESH_Mesh_i"); @@ -1077,14 +1077,17 @@ void SMESH_Mesh_i::RemoveGroupWithContents( SMESH::SMESH_GroupBase_ptr theGroup if ( _preMeshInfo ) _preMeshInfo->FullLoadFromFile(); - if ( theGroup->_is_nil() || theGroup->IsEmpty() ) + if ( theGroup->_is_nil() ) return; vector nodeIds; // to remove nodes becoming free - CORBA::Long elemID = theGroup->GetID( 1 ); - int nbElemNodes = GetElemNbNodes( elemID ); - if ( nbElemNodes > 0 ) - nodeIds.reserve( theGroup->Size() * nbElemNodes ); + if ( !theGroup->IsEmpty() ) + { + CORBA::Long elemID = theGroup->GetID( 1 ); + int nbElemNodes = GetElemNbNodes( elemID ); + if ( nbElemNodes > 0 ) + nodeIds.reserve( theGroup->Size() * nbElemNodes ); + } // Remove contents SMESH::SMESH_IDSource_var idSrc = SMESH::SMESH_IDSource::_narrow( theGroup );