Imp 19925 - Mesh preview

This commit is contained in:
ptv 2008-12-01 12:08:28 +00:00
parent 9bda958b02
commit 19d95d1426
15 changed files with 192 additions and 59 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 750 B

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.2 KiB

View File

@ -33,6 +33,7 @@
<li>\ref constructing_submeshes_page</li>
<li>\ref building_compounds_page</li>
<li>\ref editing_meshes_page</li>
<li>\ref preview_meshes_page</li>
</ul>
<li>\subpage viewing_meshes_page</li>
<ul>

View File

@ -0,0 +1,36 @@
/*!
\page preview_meshes_page Preview and Compute meshes
Before whole mesh computation it is allowed to see the mesh preview.
When mesh object is already created and all hypotheses assigned,
select your mesh in the <b>Object Browser</b>. From the
\b Mesh menu select \b Preview or click "Preview" button of the
toolbar or activate "Preview" item from pop-up menu.
\image html mesh_precompute.png
<center><em>"Preview" button</em></center>
The Mesh Preview dialog box appears. In this dialog box you can select
preview mode <b>1D mesh</b> or <b>2D mesh</b> depending on assigned
hypotheses to mesh.
The 1D mesh preview shows as nodes computed on geometry edges
\image html preview_mesh_1D.png
The 2D mesh preview shows edge mesh elements, computed on geometry faces
\image html preview_mesh_2D.png
Pressing <b>Compute</b> button leads to whole mesh computation
process.
During exit from Preview dialog box, the question about storage temporary
created mesh elements appers:
\image html preview_tmp_data.png
Note, that computed temporary mesh elements can be reused during next
mesh computation process.
*/

View File

@ -221,6 +221,17 @@ module SMESH
in GEOM::GEOM_Object theSubObject )
raises ( SALOME::SALOME_Exception );
/*!
* Calculate Mesh as preview till indicated dimension
* First, verify list of hypothesis associated with the subShape.
* Return mesh preview structure
*/
MeshPreviewStruct Precompute( in SMESH_Mesh theMesh,
in GEOM::GEOM_Object theSubObject,
in Dimension theDimension,
inout long_array theShapesId )
raises ( SALOME::SALOME_Exception );
/*!
* Return errors of hypotheses definintion
* algo_error_array is empty if everything is OK

View File

@ -228,6 +228,12 @@ module SMESH
void Clear()
raises (SALOME::SALOME_Exception);
/*!
* Remove all nodes and elements of submesh
*/
void ClearSubMesh(in long ShapeID)
raises (SALOME::SALOME_Exception);
/*!
* Get the subMesh object associated to a subShape. The subMesh object
* gives access to nodes and elements IDs.

View File

@ -129,9 +129,11 @@ SMESH_Mesh* SMESH_Gen::CreateMesh(int theStudyId, bool theIsEmbeddedMode)
*/
//=============================================================================
bool SMESH_Gen::Compute(SMESH_Mesh & aMesh,
const TopoDS_Shape & aShape,
const bool anUpward)
bool SMESH_Gen::Compute(SMESH_Mesh & aMesh,
const TopoDS_Shape & aShape,
const bool anUpward,
const ::MeshDimension aDim,
TSetOfInt* aShapesId)
{
MESSAGE("SMESH_Gen::Compute");
@ -155,16 +157,22 @@ bool SMESH_Gen::Compute(SMESH_Mesh & aMesh,
SMESH_subMesh* smToCompute = smIt->next();
// do not mesh vertices of a pseudo shape
if ( !aMesh.HasShapeToMesh() &&
smToCompute->GetSubShape().ShapeType() == TopAbs_VERTEX )
const TopAbs_ShapeEnum aShType = smToCompute->GetSubShape().ShapeType();
if ( !aMesh.HasShapeToMesh() && aShType == TopAbs_VERTEX )
continue;
// check for preview dimension limitations
if ( aShapesId && GetShapeDim( aShType ) > (int)aDim )
continue;
if (smToCompute->GetComputeState() == SMESH_subMesh::READY_TO_COMPUTE)
smToCompute->ComputeStateEngine( SMESH_subMesh::COMPUTE );
// we check all the submeshes here and detect if any of them failed to compute
if (smToCompute->GetComputeState() == SMESH_subMesh::FAILED_TO_COMPUTE)
ret = false;
else if ( aShapesId )
aShapesId->insert( smToCompute->GetId() );
}
return ret;
}
@ -184,7 +192,12 @@ bool SMESH_Gen::Compute(SMESH_Mesh & aMesh,
continue;
const TopoDS_Shape& aSubShape = smToCompute->GetSubShape();
if ( GetShapeDim( aSubShape ) < 1 ) break;
const int aShapeDim = GetShapeDim( aSubShape );
if ( aShapeDim < 1 ) break;
// check for preview dimension limitations
if ( aShapesId && aShapeDim > (int)aDim )
continue;
SMESH_Algo* algo = GetAlgo( aMesh, aSubShape );
if ( algo && !algo->NeedDescretBoundary() )
@ -192,7 +205,11 @@ bool SMESH_Gen::Compute(SMESH_Mesh & aMesh,
if ( algo->SupportSubmeshes() )
smWithAlgoSupportingSubmeshes.push_back( smToCompute );
else
{
smToCompute->ComputeStateEngine( SMESH_subMesh::COMPUTE );
if ( aShapesId )
aShapesId->insert( smToCompute->GetId() );
}
}
}
// ------------------------------------------------------------
@ -219,7 +236,13 @@ bool SMESH_Gen::Compute(SMESH_Mesh & aMesh,
SMESH_subMesh* smToCompute = smIt->next();
const TopoDS_Shape& aSubShape = smToCompute->GetSubShape();
if ( aSubShape.ShapeType() == TopAbs_VERTEX ) continue;
const int aShapeDim = GetShapeDim( aSubShape );
//if ( aSubShape.ShapeType() == TopAbs_VERTEX ) continue;
if ( aShapeDim < 1 ) continue;
// check for preview dimension limitations
if ( aShapesId && GetShapeDim( aSubShape.ShapeType() ) > (int)aDim )
continue;
SMESH_HypoFilter filter( SMESH_HypoFilter::IsAlgo() );
filter
@ -230,7 +253,7 @@ bool SMESH_Gen::Compute(SMESH_Mesh & aMesh,
SMESH_Hypothesis::Hypothesis_Status status;
if ( subAlgo->CheckHypothesis( aMesh, aSubShape, status ))
// mesh a lower smToCompute starting from vertices
Compute( aMesh, aSubShape, /*anUpward=*/true );
Compute( aMesh, aSubShape, /*anUpward=*/true, aDim, aShapesId );
}
}
}
@ -239,12 +262,21 @@ bool SMESH_Gen::Compute(SMESH_Mesh & aMesh,
// ----------------------------------------------------------
for ( subIt = smWithAlgoSupportingSubmeshes.rbegin(); subIt != subEnd; ++subIt )
if ( sm->GetComputeState() == SMESH_subMesh::READY_TO_COMPUTE)
{
const TopAbs_ShapeEnum aShType = sm->GetSubShape().ShapeType();
// check for preview dimension limitations
if ( aShapesId && GetShapeDim( aShType ) > (int)aDim )
continue;
sm->ComputeStateEngine( SMESH_subMesh::COMPUTE );
if ( aShapesId )
aShapesId->insert( sm->GetId() );
}
// -----------------------------------------------
// mesh the rest subshapes starting from vertices
// -----------------------------------------------
ret = Compute( aMesh, aShape, /*anUpward=*/true );
ret = Compute( aMesh, aShape, /*anUpward=*/true, aDim, aShapesId );
}
MESSAGE( "VSR - SMESH_Gen::Compute() finished, OK = " << ret);
@ -708,14 +740,14 @@ int SMESH_Gen::GetShapeDim(const TopAbs_ShapeEnum & aShapeType)
if ( dim.empty() )
{
dim.resize( TopAbs_SHAPE, -1 );
dim[ TopAbs_COMPOUND ] = 3;
dim[ TopAbs_COMPSOLID ] = 3;
dim[ TopAbs_SOLID ] = 3;
dim[ TopAbs_SHELL ] = 3;
dim[ TopAbs_FACE ] = 2;
dim[ TopAbs_WIRE ] = 1;
dim[ TopAbs_EDGE ] = 1;
dim[ TopAbs_VERTEX ] = 0;
dim[ TopAbs_COMPOUND ] = MeshDim_3D;
dim[ TopAbs_COMPSOLID ] = MeshDim_3D;
dim[ TopAbs_SOLID ] = MeshDim_3D;
dim[ TopAbs_SHELL ] = MeshDim_3D;
dim[ TopAbs_FACE ] = MeshDim_2D;
dim[ TopAbs_WIRE ] = MeshDim_1D;
dim[ TopAbs_EDGE ] = MeshDim_1D;
dim[ TopAbs_VERTEX ] = MeshDim_0D;
}
return dim[ aShapeType ];
}

View File

@ -45,6 +45,7 @@
#include <TopoDS_Shape.hxx>
#include <map>
#include <list>
class SMESHDS_Document;
@ -57,6 +58,8 @@ typedef struct studyContextStruct
SMESHDS_Document * myDocument;
} StudyContextStruct;
typedef std::set<int> TSetOfInt;
class SMESH_EXPORT SMESH_Gen
{
public:
@ -69,11 +72,15 @@ class SMESH_EXPORT SMESH_Gen
/*!
* \brief Computes aMesh on aShape
* \param anUpward - compute from vertices up to more complex shape (internal usage)
* \param aDim - upper level dimension of the mesh computation
* \param aShapesId - list of shapes with computed mesh entities (elements or nodes)
* \retval bool - true if none submesh failed to compute
*/
bool Compute(::SMESH_Mesh & aMesh,
const TopoDS_Shape & aShape,
const bool anUpward=false);
bool Compute(::SMESH_Mesh & aMesh,
const TopoDS_Shape & aShape,
const bool anUpward=false,
const ::MeshDimension aDim=::MeshDim_3D,
TSetOfInt* aShapesId=0);
bool CheckAlgoState(SMESH_Mesh& aMesh, const TopoDS_Shape& aShape);
// notify on bad state of attached algos, return false

View File

@ -37,6 +37,14 @@ class SMESH_Gen;
class TopoDS_Shape;
class SMESH_Mesh;
enum MeshDimension // dimension of mesh
{
MeshDim_0D,
MeshDim_1D,
MeshDim_2D,
MeshDim_3D
};
class SMESH_EXPORT SMESH_Hypothesis: public SMESHDS_Hypothesis
{
public:

View File

@ -265,6 +265,32 @@ void SMESH_Mesh::Clear()
// }
}
//=======================================================================
/*!
* \brief Remove all nodes and elements of indicated shape
*/
//=======================================================================
void SMESH_Mesh::ClearSubMesh(const int theShapeId)
{
// clear sub-meshes; get ready to re-compute as a side-effect
if ( SMESH_subMesh *sm = GetSubMeshContaining( theShapeId ) )
{
SMESH_subMeshIteratorPtr smIt = sm->getDependsOnIterator(/*includeSelf=*/true,
/*complexShapeFirst=*/false);
while ( smIt->more() )
{
sm = smIt->next();
TopAbs_ShapeEnum shapeType = sm->GetSubShape().ShapeType();
if ( shapeType == TopAbs_VERTEX || shapeType < TopAbs_SOLID )
// all other shapes depends on vertices so they are already cleaned
sm->ComputeStateEngine( SMESH_subMesh::CLEAN );
// to recompute even if failed
sm->ComputeStateEngine( SMESH_subMesh::CHECK_COMPUTE_STATE );
}
}
}
//=======================================================================
//function : UNVToMesh
//purpose :

View File

@ -87,6 +87,11 @@ public:
*/
void Clear();
/*!
* \brief Remove all nodes and elements of indicated shape
*/
void ClearSubMesh(const int theShapeId);
int UNVToMesh(const char* theFileName);
/*!
* consult DriverMED_R_SMESHDS_Mesh::ReadStatus for returned value

View File

@ -92,22 +92,6 @@ struct TNodeXYZ : public gp_XYZ {
TNodeXYZ( const SMDS_MeshNode* n ):gp_XYZ( n->X(), n->Y(), n->Z() ) {}
};
typedef pair< const SMDS_MeshNode*, const SMDS_MeshNode* > NLink;
//=======================================================================
/*!
* \brief A sorted pair of nodes
*/
//=======================================================================
struct TLink: public NLink
{
TLink(const SMDS_MeshNode* n1, const SMDS_MeshNode* n2 ):NLink( n1, n2 )
{ if ( n1->GetID() < n2->GetID() ) std::swap( first, second ); }
TLink(const NLink& link ):NLink( link )
{ if ( first->GetID() < second->GetID() ) std::swap( first, second ); }
};
//=======================================================================
//function : SMESH_MeshEditor
//purpose :
@ -1460,10 +1444,10 @@ bool SMESH_MeshEditor::TriToQuad (TIDSortedElemSet & theElems,
// 1. map of elements with their linkIDs
// 2. map of linkIDs with their elements
map< TLink, list< const SMDS_MeshElement* > > mapLi_listEl;
map< TLink, list< const SMDS_MeshElement* > >::iterator itLE;
map< const SMDS_MeshElement*, set< TLink > > mapEl_setLi;
map< const SMDS_MeshElement*, set< TLink > >::iterator itEL;
map< SMESH_TLink, list< const SMDS_MeshElement* > > mapLi_listEl;
map< SMESH_TLink, list< const SMDS_MeshElement* > >::iterator itLE;
map< const SMDS_MeshElement*, set< SMESH_TLink > > mapEl_setLi;
map< const SMDS_MeshElement*, set< SMESH_TLink > >::iterator itEL;
TIDSortedElemSet::iterator itElem;
for ( itElem = theElems.begin(); itElem != theElems.end(); itElem++ ) {
@ -1482,7 +1466,7 @@ bool SMESH_MeshEditor::TriToQuad (TIDSortedElemSet & theElems,
// fill maps
for ( i = 0; i < 3; i++ ) {
TLink link( aNodes[i], aNodes[i+1] );
SMESH_TLink link( aNodes[i], aNodes[i+1] );
// check if elements sharing a link can be fused
itLE = mapLi_listEl.find( link );
if ( itLE != mapLi_listEl.end() ) {
@ -1508,7 +1492,7 @@ bool SMESH_MeshEditor::TriToQuad (TIDSortedElemSet & theElems,
int nbElems = (*itLE).second.size();
if ( nbElems < 2 ) {
const SMDS_MeshElement* elem = (*itLE).second.front();
TLink link = (*itLE).first;
SMESH_TLink link = (*itLE).first;
mapEl_setLi[ elem ].erase( link );
if ( mapEl_setLi[ elem ].empty() )
mapEl_setLi.erase( elem );
@ -1534,11 +1518,11 @@ bool SMESH_MeshEditor::TriToQuad (TIDSortedElemSet & theElems,
// search elements to fuse starting from startElem or links of elements
// fused earlyer - startLinks
list< TLink > startLinks;
list< SMESH_TLink > startLinks;
while ( startElem || !startLinks.empty() ) {
while ( !startElem && !startLinks.empty() ) {
// Get an element to start, by a link
TLink linkId = startLinks.front();
SMESH_TLink linkId = startLinks.front();
startLinks.pop_front();
itLE = mapLi_listEl.find( linkId );
if ( itLE != mapLi_listEl.end() ) {
@ -1554,15 +1538,15 @@ bool SMESH_MeshEditor::TriToQuad (TIDSortedElemSet & theElems,
if ( startElem ) {
// Get candidates to be fused
const SMDS_MeshElement *tr1 = startElem, *tr2 = 0, *tr3 = 0;
const TLink *link12, *link13;
const SMESH_TLink *link12, *link13;
startElem = 0;
ASSERT( mapEl_setLi.find( tr1 ) != mapEl_setLi.end() );
set< TLink >& setLi = mapEl_setLi[ tr1 ];
set< SMESH_TLink >& setLi = mapEl_setLi[ tr1 ];
ASSERT( !setLi.empty() );
set< TLink >::iterator itLi;
set< SMESH_TLink >::iterator itLi;
for ( itLi = setLi.begin(); itLi != setLi.end(); itLi++ )
{
const TLink & link = (*itLi);
const SMESH_TLink & link = (*itLi);
itLE = mapLi_listEl.find( link );
if ( itLE == mapLi_listEl.end() )
continue;
@ -1583,10 +1567,10 @@ bool SMESH_MeshEditor::TriToQuad (TIDSortedElemSet & theElems,
}
// add other links of elem to list of links to re-start from
set< TLink >& links = mapEl_setLi[ elem ];
set< TLink >::iterator it;
set< SMESH_TLink >& links = mapEl_setLi[ elem ];
set< SMESH_TLink >::iterator it;
for ( it = links.begin(); it != links.end(); it++ ) {
const TLink& link2 = (*it);
const SMESH_TLink& link2 = (*it);
if ( link2 != link )
startLinks.push_back( link2 );
}
@ -2443,9 +2427,8 @@ void SMESH_MeshEditor::Smooth (TIDSortedElemSet & theElems,
// fix nodes on mesh boundary
if ( checkBoundaryNodes ) {
typedef pair<const SMDS_MeshNode*, const SMDS_MeshNode*> TLink;
map< TLink, int > linkNbMap; // how many times a link encounters in elemsOnFace
map< TLink, int >::iterator link_nb;
map< NLink, int > linkNbMap; // how many times a link encounters in elemsOnFace
map< NLink, int >::iterator link_nb;
// put all elements links to linkNbMap
list< const SMDS_MeshElement* >::iterator elemIt = elemsOnFace.begin();
for ( ; elemIt != elemsOnFace.end(); ++elemIt ) {
@ -2457,7 +2440,7 @@ void SMESH_MeshEditor::Smooth (TIDSortedElemSet & theElems,
const SMDS_MeshNode* curNode, *prevNode = elem->GetNode( nbn );
for ( int iN = 0; iN < nbn; ++iN ) {
curNode = elem->GetNode( iN );
TLink link;
NLink link;
if ( curNode < prevNode ) link = make_pair( curNode , prevNode );
else link = make_pair( prevNode , curNode );
prevNode = curNode;
@ -7541,8 +7524,8 @@ SMESH_MeshEditor::FindMatchingNodes(set<const SMDS_MeshElement*>& theSide1,
if ( theSecondNode1 != theSecondNode2 )
nReplaceMap.insert( make_pair( theSecondNode1, theSecondNode2 ));
set< TLink > linkSet; // set of nodes where order of nodes is ignored
linkSet.insert( TLink( theFirstNode1, theSecondNode1 ));
set< SMESH_TLink > linkSet; // set of nodes where order of nodes is ignored
linkSet.insert( SMESH_TLink( theFirstNode1, theSecondNode1 ));
list< NLink > linkList[2];
linkList[0].push_back( NLink( theFirstNode1, theSecondNode1 ));
@ -7657,8 +7640,8 @@ SMESH_MeshEditor::FindMatchingNodes(set<const SMDS_MeshElement*>& theSide1,
for ( int i = 0; i < nbN; i++ )
{
const SMDS_MeshNode* n2 = f0->GetNode( i );
pair< set< TLink >::iterator, bool > iter_isnew =
linkSet.insert( TLink( n1, n2 ));
pair< set< SMESH_TLink >::iterator, bool > iter_isnew =
linkSet.insert( SMESH_TLink( n1, n2 ));
if ( !iter_isnew.second ) { // already in a set: no need to process
linkSet.erase( iter_isnew.first );
}

View File

@ -49,6 +49,24 @@ typedef std::map<const SMDS_MeshElement*,
std::list<const SMDS_MeshElement*> > TElemOfElemListMap;
typedef std::map<const SMDS_MeshNode*, const SMDS_MeshNode*> TNodeNodeMap;
typedef pair< const SMDS_MeshNode*, const SMDS_MeshNode* > NLink;
//=======================================================================
/*!
* \brief A sorted pair of nodes
*/
//=======================================================================
struct SMESH_TLink: public NLink
{
SMESH_TLink(const SMDS_MeshNode* n1, const SMDS_MeshNode* n2 ):NLink( n1, n2 )
{ if ( n1->GetID() < n2->GetID() ) std::swap( first, second ); }
SMESH_TLink(const NLink& link ):NLink( link )
{ if ( first->GetID() < second->GetID() ) std::swap( first, second ); }
};
class SMDS_MeshFace;
class SMDS_MeshNode;
class gp_Ax1;