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:
<ul>
<li>\subpage a1d_meshing_hypo_page "1D Hypotheses" (for meshing of
</ul>
There also exist
-\subpage additional_hypo_page "Additional Hypotheses" that can be used together
-with main hypotheses:
+\subpage additional_hypo_page "Additional Hypotheses":
<ul>
<li>\ref propagation_anchor "Propagation of 1D Hypothesis on opposite edges"</li>
<li>\ref propagofdistribution_anchor "Propagation of Node Distribution on Opposite Edges"</li>
<li>\ref quadrangle_preference_anchor "Quadrangle preference"</li>
</ul>
-The choice of a hypothesis depends on the selected algorithm.
-
*/
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.<br>
Meshing parameters of meshes and sub-meshes can be
\subpage editing_meshes_page "edited". (Upon edition only mesh entities
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
<ul>
<li><em>Triangle (Mefisto)</em> meshing algorithm - splits faces
into triangular elements.</li>
-<li><em>Quadrangle (Mapping)</em> meshing algorithm - splits faces
- into quadrangular elements.</li>
+<li>\subpage quad_ijk_algo_page "Quadrangle (Mapping)" meshing
+ algorithm - splits faces into quadrangular elements.</li>
</ul>
\image html image123.gif "Example of a triangular 2D mesh"
\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
following pop-up menu allowing to choose a way of geometry definition will
appear.
-\par
\image html choose_geom_selection_way.png
-\par
<b>Direct geometry selection</b> enables selecting the sub-shape in the Object
Browser.
<b>Find geometry by mesh element selection</b> activates the following dialog.
-\par
\image html find_geom_by_mesh_elem.png
-\par
In this dialog, <b> Element Type </b> defines a kind of element to pick in the
Viewer.
Instead of picking an element in the Viewer, you can type its
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:
<ul>
<li>a sub-mesh name (\a SubMeshFace1)
<li>a reference to the geometrical object on the basis of which the
sub-mesh has been constructed (<em>Cylindrical Face_1</em>);</li>
-<li><b>Applied hypotheses</b> folder containing the references to the
-hypotheses selected at the construction of the sub-mesh;</li>
-<li><b>Applied algorithms</b> folder containing the references to the
-algorithms selected at the construction of the sub-mesh.</li>
+<li><em>Applied hypotheses</em> folder containing the references to the
+hypotheses assigned to the sub-mesh;</li>
+<li><em>Applied algorithms</em> folder containing the references to the
+algorithms assigned to the sub-mesh.</li>
</ul>
<br><b>See Also</b> a sample TUI Script of a
\image html image122.png
<center><em>"Edit Hypothesis" button</em></center>
+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"
+<br>
\image html edit_mesh_change_value_hyp.png "And now the Max Element area is greatly reduced"
--- /dev/null
+/*!
+
+\page quad_ijk_algo_page Quadrangle (Mapping) meshing algorithm
+
+<b>Quadrangle (Mapping)</b> 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 <em>Transfinite Interpolation</em> 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.
+
+*/
#include <GEOMUtils.hxx>
#undef _Precision_HeaderFile
-//#include <BRepBndLib.hxx>
+#include <BRepBndLib.hxx>
#include <BRepPrimAPI_MakeBox.hxx>
#include <Bnd_Box.hxx>
#include <TColStd_MapOfInteger.hxx>
#include "SMESH_TryCatch.hxx" // include after OCCT headers!
#include "Utils_ExceptHandlers.hxx"
+
#ifndef WIN32
#include <boost/thread/thread.hpp>
#include <boost/bind.hpp>
#else
-#include <pthread.h>
+include <pthread.h>
#endif
using namespace std;
{
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<SMESHDS_SubMesh*>( 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))
{
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() );
}
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<SMESH_Hypothesis_i*>( tmpHyp );
if ( !hypServant )
// 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<SMESH_Mesh_i*>( anInitMesh );
{
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;
<< TVar( theTolerance ) << ", "
<< theMakeGroups << " )";
}
+ else
+ {
+ getPreviewMesh()->Remove( SMDSAbs_Volume );
+ }
return aGroups ? aGroups : new SMESH::ListOfGroups;
<< TVar( theNbOfSteps ) << ", "
<< theToMakeGroups << " )";
}
+ else
+ {
+ getPreviewMesh()->Remove( SMDSAbs_Volume );
+ }
return aGroups ? aGroups : new SMESH::ListOfGroups;
<< ", " << dim
<< " )";
}
+ else
+ {
+ getPreviewMesh()->Remove( SMDSAbs_Volume );
+ }
declareMeshModified( /*isReComputeSafe=*/true ); // does not influence Compute()
<< theSewTolerance << ", "
<< theMakeGroups << " )";
}
+ else
+ {
+ getPreviewMesh()->Remove( SMDSAbs_Volume );
+ }
return aGroups ? aGroups : new SMESH::ListOfGroups;
<< ( theHasRefPoint ? theRefPoint.z : 0 ) << " ), "
<< theMakeGroups << " )";
}
+ else
+ {
+ getPreviewMesh()->Remove( SMDSAbs_Volume );
+ }
return aGroups._retn();
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");
if ( _preMeshInfo )
_preMeshInfo->FullLoadFromFile();
- if ( theGroup->_is_nil() || theGroup->IsEmpty() )
+ if ( theGroup->_is_nil() )
return;
vector<int> 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 );