Merge from BR_phase16 branch (09/12/09)

This commit is contained in:
vsr 2009-12-09 15:46:26 +00:00
parent 2daa321efa
commit b03a1e6001
32 changed files with 1944 additions and 111 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.7 KiB

View File

@ -152,10 +152,89 @@ evaluation will be displayed in the following information box:
\image html mesh_evaluation_succeed.png
</li>
</ol>
\anchor mesh_order_anchor
It is allowed to change submesh priority in mesh computation when
there are concurrent submeshes present. I.e. user can change priority of
applying algorithms on shared subshapes of Mesh shape.
<em>To change submesh priority:</em>
<ol>
<li>From the Mesh menu choose the "Change submesh priority" on
selected Mesh item, or invoke from popup menu.
There are example of submesh order modifications of Mesh created on a Box
shape. The main Mesh object:
<ul>
<li><i>3D</i> <b>Tetrahedron (Netgen)</b> with Hypothesis<b>Max Element Volume</b></li>
<li><i>2D</i> <b>Triangle (Mefisto)</b> with Hypothesis<b>Max Element Area</b>
</li>
<li><i>1D</i> <b>Wire discretisation</b> with <b>Number of Segments</b>=20</li>
</ul>
The first submesh object <b>Submesh_1</b> created on <b>Face_1</b>
is:
<ul>
<li><i>2D</i> Netgen 1D-2D with Hypothesis <b>Netgen Simple parameters</b>
(Number of Segments = 4)</li>
</ul>
The second submesh object <b>Submesh_2</b> created on <b>Face_2</b>
is:
<ul>
<li><i>2D</i> Netgen 1D-2D with Hypothesis <b>Netgen Simple parameters</b>
(Number of Segments = 8)</li>
</ul>
And the last third submesh object <b>Submesh_3</b> created on <b>Face_3</b>
is:
<ul>
<li><i>2D</i> Netgen 1D-2D with Hypothesis <b>Netgen Simple parameters</b>
(Number of Segments = 12)</li>
</ul>
The submeshes can become concurrent if thir algorithms leads to mesh shared subshape
with different algorithms (or different algorithms parameters, i.e. hypothesises).
In fact, we have three submeshes with concurrent algorithms, becase
they has different hypothesises assigned to them.
The first mesh computation made with:
\image html mesh_order_123.png
<center><em>"Mesh order SubMesh_1, SubMesh_2, SubMesh_3"</em></center>
\image html mesh_order_123_res.png
<center><em>"Result mesh with order SubMesh_1, SubMesh_2, SubMesh_3 "</em></center>
The next mesh computation with:
\image html mesh_order_213.png
<center><em>"Mesh order SubMesh_2, SubMesh_1, SubMesh_3"</em></center>
\image html mesh_order_213_res.png
<center><em>"Result mesh with order SubMesh_2, SubMesh_1, SubMesh_3 "</em></center>
And the last mesh computation with:
\image html mesh_order_321.png
<center><em>"Mesh order SubMesh_3, SubMesh_2, SubMesh_1"</em></center>
\image html mesh_order_321_res.png
<center><em>"Result mesh with order SubMesh_3, SubMesh_2, SubMesh_1 "</em></center>
As we can see each mesh computation has different number of result
elements and different mesh descretisation on shared edges (edges,
that shared between <b>Face_1</b>, <b>Face_2</b> and <b>Face_3</b>)
Additionally, submesh priority (order of algorithms to be applied) can
be modified not only in separate dialog box, but in <b>Preview</b>
also. This helps to preview different mesh results, modifying submesh
order.
\image html mesh_order_preview.png
<center><em>"Preview with submesh priority list box"</em></center>
If no concurrent submeshes under Mesh object user will see the
following information dialog box
\image html mesh_order_no_concurrent.png
<center><em>"No concurrent submeshes detected"</em></center>
and no mesh order list box appear in Preview dialog box.
</ol>
Consider trying a sample script for construction of a mesh from our
\ref tui_creating_meshes_page "TUI Scripts" section.
</li>
</ol>
*/

View File

@ -82,6 +82,67 @@ quadra.Compute()
\endcode
<br>
<h2>Change priority of submeshes in Mesh</h2>
\code
import salome
import geompy
import smesh
import SMESH
Box_1 = geompy.MakeBoxDXDYDZ(200, 200, 200)
[Face_1,Face_2,Face_3,Face_4,Face_5,Face_6] = geompy.SubShapeAllSorted(Box_1, geompy.ShapeType["FACE"])
# create Mesh object on Box shape
Mesh_1 = smesh.Mesh(Box_1)
# assign mesh algorithms
Regular_1D = Mesh_1.Segment()
Nb_Segments_1 = Regular_1D.NumberOfSegments(20)
Nb_Segments_1.SetDistrType( 0 )
MEFISTO_2D = Mesh_1.Triangle()
Max_Element_Area_1 = MEFISTO_2D.MaxElementArea(1200)
Tetrahedron_Netgen = Mesh_1.Tetrahedron(algo=smesh.NETGEN)
Max_Element_Volume_1 = Tetrahedron_Netgen.MaxElementVolume(40000)
# create submesh and assign algorithms on Face_1
Netgen_1D_2D = Mesh_1.Triangle(algo=smesh.NETGEN,geom=Face_1)
SubMesh_1 = Netgen_1D_2D.GetSubMesh()
NETGEN_2D_Simple_Parameters_1 = Netgen_1D_2D.Parameters(which=smesh.SIMPLE)
NETGEN_2D_Simple_Parameters_1.SetNumberOfSegments( 4 )
NETGEN_2D_Simple_Parameters_1.LengthFromEdges()
# create submesh and assign algorithms on Face_2
Netgen_1D_2D_1 = Mesh_1.Triangle(algo=smesh.NETGEN,geom=Face_2)
SubMesh_2 = Netgen_1D_2D_1.GetSubMesh()
NETGEN_2D_Simple_Parameters_2 = Netgen_1D_2D_1.Parameters(which=smesh.SIMPLE)
NETGEN_2D_Simple_Parameters_2.SetNumberOfSegments( 8 )
NETGEN_2D_Simple_Parameters_2.LengthFromEdges()
smeshObj_1 = smesh.CreateHypothesis('NETGEN_SimpleParameters_2D',
'NETGENEngine')
# create submesh and assign algorithms on Face_3
Netgen_1D_2D_2 = Mesh_1.Triangle(algo=smesh.NETGEN,geom=Face_3)
SubMesh_3 = Netgen_1D_2D_2.GetSubMesh()
NETGEN_2D_Simple_Parameters_3 = Netgen_1D_2D_2.Parameters(which=smesh.SIMPLE)
NETGEN_2D_Simple_Parameters_3.SetNumberOfSegments( 12 )
NETGEN_2D_Simple_Parameters_3.LengthFromEdges()
# check exisiting submesh priority order
[ [ SubMesh_1, SubMesh_3, SubMesh_2 ] ] = Mesh_1.GetMeshOrder()
# set new submesh order
isDone = Mesh_1.SetMeshOrder( [ [ SubMesh_1, SubMesh_2, SubMesh_3 ] ])
# compute mesh
isDone = Mesh_1.Compute()
# clear mesh result and compute with other submesh order
Mesh_1.Clear()
isDone = Mesh_1.SetMeshOrder( [ [ SubMesh_2, SubMesh_1, SubMesh_3 ] ])
isDone = Mesh_1.Compute()
\endcode
<br>
\anchor tui_editing_mesh
<h2>Editing of a mesh</h2>

View File

@ -263,6 +263,10 @@ module SMESH
interface SMESH_GroupOnGeom;
interface SMESH_subMesh;
interface SMESH_MeshEditor;
typedef sequence<SMESH_subMesh> submesh_array;
typedef sequence<submesh_array> submesh_array_array;
interface SMESH_Mesh : SALOME::GenericObj, SMESH_IDSource
{
/*!
@ -661,6 +665,22 @@ module SMESH
ElementType GetSubMeshElementType(in long ShapeID)
raises (SALOME::SALOME_Exception);
/*!
* Methods to set meshing order of submeshes
*/
/*!
* \brief Return submesh objects list in meshing order
*/
submesh_array_array GetMeshOrder();
/*!
* \brief Set submesh object order
*/
boolean SetMeshOrder(in submesh_array_array theSubMeshArray);
/*!
* Get mesh description
*/

View File

@ -207,7 +207,7 @@ bool SMESH_Gen::Compute(SMESH_Mesh & aMesh,
if ( algo && !algo->NeedDescretBoundary() )
{
if ( algo->SupportSubmeshes() )
smWithAlgoSupportingSubmeshes.push_back( smToCompute );
smWithAlgoSupportingSubmeshes.push_front( smToCompute );
else
{
smToCompute->ComputeStateEngine( SMESH_subMesh::COMPUTE );
@ -216,13 +216,19 @@ bool SMESH_Gen::Compute(SMESH_Mesh & aMesh,
}
}
}
// ------------------------------------------------------------
// sort list of meshes according to mesh order
// ------------------------------------------------------------
aMesh.SortByMeshOrder( smWithAlgoSupportingSubmeshes );
// ------------------------------------------------------------
// compute submeshes under shapes with algos that DO NOT require
// descretized boundaries and DO support submeshes
// ------------------------------------------------------------
list< SMESH_subMesh* >::reverse_iterator subIt, subEnd;
subIt = smWithAlgoSupportingSubmeshes.rbegin();
subEnd = smWithAlgoSupportingSubmeshes.rend();
list< SMESH_subMesh* >::iterator subIt, subEnd;
subIt = smWithAlgoSupportingSubmeshes.begin();
subEnd = smWithAlgoSupportingSubmeshes.end();
// start from lower shapes
for ( ; subIt != subEnd; ++subIt )
{
@ -264,7 +270,7 @@ bool SMESH_Gen::Compute(SMESH_Mesh & aMesh,
// ----------------------------------------------------------
// apply the algos that do not require descretized boundaries
// ----------------------------------------------------------
for ( subIt = smWithAlgoSupportingSubmeshes.rbegin(); subIt != subEnd; ++subIt )
for ( subIt = smWithAlgoSupportingSubmeshes.begin(); subIt != subEnd; ++subIt )
{
sm = *subIt;
if ( sm->GetComputeState() == SMESH_subMesh::READY_TO_COMPUTE)
@ -353,7 +359,7 @@ bool SMESH_Gen::Evaluate(SMESH_Mesh & aMesh,
SMESH_Algo* algo = GetAlgo( aMesh, aSubShape );
if ( algo && !algo->NeedDescretBoundary() ) {
if ( algo->SupportSubmeshes() ) {
smWithAlgoSupportingSubmeshes.push_back( smToCompute );
smWithAlgoSupportingSubmeshes.push_front( smToCompute );
}
else {
smToCompute->Evaluate(aResMap);
@ -362,13 +368,19 @@ bool SMESH_Gen::Evaluate(SMESH_Mesh & aMesh,
}
}
}
// ------------------------------------------------------------
// sort list of meshes according to mesh order
// ------------------------------------------------------------
aMesh.SortByMeshOrder( smWithAlgoSupportingSubmeshes );
// ------------------------------------------------------------
// compute submeshes under shapes with algos that DO NOT require
// descretized boundaries and DO support submeshes
// ------------------------------------------------------------
list< SMESH_subMesh* >::reverse_iterator subIt, subEnd;
subIt = smWithAlgoSupportingSubmeshes.rbegin();
subEnd = smWithAlgoSupportingSubmeshes.rend();
list< SMESH_subMesh* >::iterator subIt, subEnd;
subIt = smWithAlgoSupportingSubmeshes.begin();
subEnd = smWithAlgoSupportingSubmeshes.end();
// start from lower shapes
for ( ; subIt != subEnd; ++subIt ) {
sm = *subIt;
@ -405,7 +417,7 @@ bool SMESH_Gen::Evaluate(SMESH_Mesh & aMesh,
// ----------------------------------------------------------
// apply the algos that do not require descretized boundaries
// ----------------------------------------------------------
for ( subIt = smWithAlgoSupportingSubmeshes.rbegin(); subIt != subEnd; ++subIt )
for ( subIt = smWithAlgoSupportingSubmeshes.begin(); subIt != subEnd; ++subIt )
{
sm = *subIt;
sm->Evaluate(aResMap);

View File

@ -175,14 +175,8 @@ void SMESH_Mesh::ShapeToMesh(const TopoDS_Shape & aShape)
_isShapeToMesh = true;
_nbSubShapes = _myMeshDS->MaxShapeIndex();
// fill _mapAncestors
int desType, ancType;
for ( desType = TopAbs_VERTEX; desType > TopAbs_COMPOUND; desType-- )
for ( ancType = desType - 1; ancType >= TopAbs_COMPOUND; ancType-- )
TopExp::MapShapesAndAncestors ( aShape,
(TopAbs_ShapeEnum) desType,
(TopAbs_ShapeEnum) ancType,
_mapAncestors );
// fill map of ancestors
fillAncestorsMap(aShape);
}
else
{
@ -479,33 +473,6 @@ SMESH_Hypothesis::Hypothesis_Status
if ( !subMesh || !subMesh->GetId())
return SMESH_Hypothesis::HYP_BAD_SUBSHAPE;
SMESHDS_SubMesh *subMeshDS = subMesh->GetSubMeshDS();
if ( subMeshDS && subMeshDS->IsComplexSubmesh() ) // group of sub-shapes and maybe of not sub-
{
MESSAGE("AddHypothesis() to complex submesh");
// return the worst but not fatal state of all group memebers
SMESH_Hypothesis::Hypothesis_Status aBestRet, aWorstNotFatal, ret;
aBestRet = SMESH_Hypothesis::HYP_BAD_DIM;
aWorstNotFatal = SMESH_Hypothesis::HYP_OK;
for ( TopoDS_Iterator itS ( aSubShape ); itS.More(); itS.Next())
{
if ( !GetMeshDS()->ShapeToIndex( itS.Value() ))
continue; // not sub-shape
ret = AddHypothesis( itS.Value(), anHypId );
if ( !SMESH_Hypothesis::IsStatusFatal( ret ) && ret > aWorstNotFatal )
aWorstNotFatal = ret;
if ( ret < aBestRet )
aBestRet = ret;
}
// bind hypotheses to a group just to know
SMESH_Hypothesis *anHyp = _gen->GetStudyContext(_studyId)->mapHypothesis[anHypId];
GetMeshDS()->AddHypothesis( aSubShape, anHyp );
if ( SMESH_Hypothesis::IsStatusFatal( aBestRet ))
return aBestRet;
return aWorstNotFatal;
}
StudyContextStruct *sc = _gen->GetStudyContext(_studyId);
if (sc->mapHypothesis.find(anHypId) == sc->mapHypothesis.end())
{
@ -586,32 +553,6 @@ SMESH_Hypothesis::Hypothesis_Status
Unexpect aCatch(SalomeException);
if(MYDEBUG) MESSAGE("SMESH_Mesh::RemoveHypothesis");
SMESH_subMesh *subMesh = GetSubMesh(aSubShape);
SMESHDS_SubMesh *subMeshDS = subMesh->GetSubMeshDS();
if ( subMeshDS && subMeshDS->IsComplexSubmesh() )
{
// return the worst but not fatal state of all group memebers
SMESH_Hypothesis::Hypothesis_Status aBestRet, aWorstNotFatal, ret;
aBestRet = SMESH_Hypothesis::HYP_BAD_DIM;
aWorstNotFatal = SMESH_Hypothesis::HYP_OK;
for ( TopoDS_Iterator itS ( aSubShape ); itS.More(); itS.Next())
{
if ( !GetMeshDS()->ShapeToIndex( itS.Value() ))
continue; // not sub-shape
ret = RemoveHypothesis( itS.Value(), anHypId );
if ( !SMESH_Hypothesis::IsStatusFatal( ret ) && ret > aWorstNotFatal )
aWorstNotFatal = ret;
if ( ret < aBestRet )
aBestRet = ret;
}
SMESH_Hypothesis *anHyp = _gen->GetStudyContext(_studyId)->mapHypothesis[anHypId];
GetMeshDS()->RemoveHypothesis( aSubShape, anHyp );
if ( SMESH_Hypothesis::IsStatusFatal( aBestRet ))
return aBestRet;
return aWorstNotFatal;
}
StudyContextStruct *sc = _gen->GetStudyContext(_studyId);
if (sc->mapHypothesis.find(anHypId) == sc->mapHypothesis.end())
throw SALOME_Exception(LOCALIZED("hypothesis does not exist"));
@ -625,6 +566,8 @@ SMESH_Hypothesis::Hypothesis_Status
bool isAlgo = ( !anHyp->GetType() == SMESHDS_Hypothesis::PARAM_ALGO );
int event = isAlgo ? SMESH_subMesh::REMOVE_ALGO : SMESH_subMesh::REMOVE_HYP;
SMESH_subMesh *subMesh = GetSubMesh(aSubShape);
SMESH_Hypothesis::Hypothesis_Status ret = subMesh->AlgoStateEngine(event, anHyp);
// there may appear concurrent hyps that were covered by the removed hyp
@ -709,15 +652,18 @@ const SMESH_Hypothesis * SMESH_Mesh::GetHypothesis(const TopoDS_Shape & aSubS
}
if ( andAncestors )
{
TopTools_ListIteratorOfListOfShape it( GetAncestors( aSubShape ));
for (; it.More(); it.Next() )
// user sorted submeshes of ancestors, according to stored submesh priority
const std::list<SMESH_subMesh*> smList = getAncestorsSubMeshes( aSubShape );
std::list<SMESH_subMesh*>::const_iterator smIt = smList.begin();
for ( ; smIt != smList.end(); smIt++ )
{
const std::list<const SMESHDS_Hypothesis*>& hypList = _myMeshDS->GetHypothesis(it.Value());
const TopoDS_Shape& curSh = (*smIt)->GetSubShape();
const std::list<const SMESHDS_Hypothesis*>& hypList = _myMeshDS->GetHypothesis(curSh);
std::list<const SMESHDS_Hypothesis*>::const_iterator hyp = hypList.begin();
for ( ; hyp != hypList.end(); hyp++ ) {
const SMESH_Hypothesis * h = cSMESH_Hyp( *hyp );
if (aFilter.IsOk( h, it.Value() )) {
if ( assignedTo ) *assignedTo = it.Value();
if (aFilter.IsOk( h, curSh )) {
if ( assignedTo ) *assignedTo = curSh;
return h;
}
}
@ -776,14 +722,18 @@ int SMESH_Mesh::GetHypotheses(const TopoDS_Shape & aSubShape,
if ( andAncestors )
{
TopTools_MapOfShape map;
TopTools_ListIteratorOfListOfShape it( GetAncestors( aSubShape ));
for (; it.More(); it.Next() )
// user sorted submeshes of ancestors, according to stored submesh priority
const std::list<SMESH_subMesh*> smList = getAncestorsSubMeshes( aSubShape );
std::list<SMESH_subMesh*>::const_iterator smIt = smList.begin();
for ( ; smIt != smList.end(); smIt++ )
{
if ( !map.Add( it.Value() ))
const TopoDS_Shape& curSh = (*smIt)->GetSubShape();
if ( !map.Add( curSh ))
continue;
const std::list<const SMESHDS_Hypothesis*>& hypList = _myMeshDS->GetHypothesis(it.Value());
const std::list<const SMESHDS_Hypothesis*>& hypList = _myMeshDS->GetHypothesis(curSh);
for ( hyp = hypList.begin(); hyp != hypList.end(); hyp++ )
if (aFilter.IsOk( cSMESH_Hyp( *hyp ), it.Value() ) &&
if (aFilter.IsOk( cSMESH_Hyp( *hyp ), curSh ) &&
( cSMESH_Hyp(*hyp)->IsAuxiliary() || !mainHypFound ) &&
hypTypes.insert( (*hyp)->GetName() ).second )
{
@ -842,6 +792,9 @@ SMESH_subMesh *SMESH_Mesh::GetSubMesh(const TopoDS_Shape & aSubShape)
{
index = _myMeshDS->AddCompoundSubmesh( aSubShape, it.Value().ShapeType() );
if ( index > _nbSubShapes ) _nbSubShapes = index; // not to create sm for this group again
// fill map of Ancestors
fillAncestorsMap(aSubShape);
}
}
// if ( !index )
@ -856,6 +809,7 @@ SMESH_subMesh *SMESH_Mesh::GetSubMesh(const TopoDS_Shape & aSubShape)
{
aSubMesh = new SMESH_subMesh(index, this, _myMeshDS, aSubShape);
_mapSubMesh[index] = aSubMesh;
ClearMeshOrder();
}
return aSubMesh;
}
@ -1580,3 +1534,138 @@ SMESH_Group* SMESH_Mesh::ConvertToStandalone ( int theGroupID )
return aGroup;
}
//=============================================================================
/*!
* \brief remove submesh order from Mesh
*/
//=============================================================================
void SMESH_Mesh::ClearMeshOrder()
{
_mySubMeshOrder.clear();
}
//=============================================================================
/*!
* \brief remove submesh order from Mesh
*/
//=============================================================================
void SMESH_Mesh::SetMeshOrder(const TListOfListOfInt& theOrder )
{
_mySubMeshOrder = theOrder;
}
//=============================================================================
/*!
* \brief return submesh order if any
*/
//=============================================================================
const TListOfListOfInt& SMESH_Mesh::GetMeshOrder() const
{
return _mySubMeshOrder;
}
//=============================================================================
/*!
* \brief fillAncestorsMap
*/
//=============================================================================
void SMESH_Mesh::fillAncestorsMap(const TopoDS_Shape& theShape)
{
// fill _mapAncestors
int desType, ancType;
for ( desType = TopAbs_VERTEX; desType > TopAbs_COMPOUND; desType-- )
for ( ancType = desType - 1; ancType >= TopAbs_COMPOUND; ancType-- )
TopExp::MapShapesAndAncestors ( theShape,
(TopAbs_ShapeEnum) desType,
(TopAbs_ShapeEnum) ancType,
_mapAncestors );
}
//=============================================================================
/*!
* \brief sort submeshes according to stored mesh order
* \param theListToSort in out list to be sorted
* \return FALSE if nothing sorted
*/
//=============================================================================
bool SMESH_Mesh::SortByMeshOrder(std::list<SMESH_subMesh*>& theListToSort) const
{
if ( !_mySubMeshOrder.size() || theListToSort.size() < 2)
return true;
bool res = false;
std::list<SMESH_subMesh*> onlyOrderedList;
// collect all ordered submeshes in one list as pointers
TListOfListOfInt::const_iterator listIddIt = _mySubMeshOrder.begin();
for( ; listIddIt != _mySubMeshOrder.end(); listIddIt++) {
const TListOfInt& listOfId = *listIddIt;
TListOfInt::const_iterator idIt = listOfId.begin();
for ( ; idIt != listOfId.end(); idIt++ ) {
map <int, SMESH_subMesh *>::const_iterator i_sm = _mapSubMesh.find(*idIt);
if ( i_sm != _mapSubMesh.end() )
onlyOrderedList.push_back(i_sm->second);
}
}
if (!onlyOrderedList.size())
return res;
std::list<SMESH_subMesh*>::iterator onlyBIt = onlyOrderedList.begin();
std::list<SMESH_subMesh*>::iterator onlyEIt = onlyOrderedList.end();
// check positions where ordered submeshes should be in result list
std::set<int> setOfPos; // remember positions of in set
std::list<SMESH_subMesh*>::const_iterator smIt = theListToSort.begin();
int i = 0;
for( ; smIt != theListToSort.end(); i++, smIt++ )
if ( find( onlyBIt, onlyEIt, *smIt ) != onlyEIt )
setOfPos.insert(i);
if ( !setOfPos.size() )
return res;
// new list of all submeshes to be sorted
std::list<SMESH_subMesh*> aNewList;
// iterates on submeshes and insert ordered in detected positions
for ( i = 0, smIt = theListToSort.begin(); smIt != theListToSort.end(); i++, smIt++ )
if ( setOfPos.find( i ) != setOfPos.end() &&
onlyBIt != onlyEIt ) { // position of ordered submesh detected
aNewList.push_back( *onlyBIt ); // ordered submesh
onlyBIt++;
}
else
aNewList.push_back( *smIt ); // other submesh from list
theListToSort = aNewList;
return res;
}
//=============================================================================
/*!
* \brief sort submeshes according to stored mesh order
* \param theListToSort in out list to be sorted
* \return FALSE if nothing sorted
*/
//=============================================================================
std::list<SMESH_subMesh*> SMESH_Mesh::getAncestorsSubMeshes
(const TopoDS_Shape& theSubShape) const
{
std::list<SMESH_subMesh*> listOfSubMesh;
TopTools_ListIteratorOfListOfShape it( GetAncestors( theSubShape ));
for (; it.More(); it.Next() ) {
int index = _myMeshDS->ShapeToIndex(it.Value());
map <int, SMESH_subMesh *>::const_iterator i_sm = _mapSubMesh.find(index);
if (i_sm != _mapSubMesh.end())
listOfSubMesh.push_back(i_sm->second);
}
// sort submeshes according to stored mesh order
SortByMeshOrder( listOfSubMesh );
return listOfSubMesh;
}

View File

@ -40,8 +40,8 @@
#include <TopoDS_Shape.hxx>
#include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
#include <list>
#include <map>
#include <list>
class SMESH_Gen;
class SMESHDS_Document;
@ -51,6 +51,9 @@ class SMESH_subMesh;
class SMESH_HypoFilter;
class TopoDS_Solid;
typedef std::list<int> TListOfInt;
typedef std::list<TListOfInt> TListOfListOfInt;
class SMESH_EXPORT SMESH_Mesh
{
public:
@ -248,12 +251,27 @@ public:
SMDSAbs_ElementType GetElementType( const int id, const bool iselem );
void ClearMeshOrder();
void SetMeshOrder(const TListOfListOfInt& theOrder );
const TListOfListOfInt& GetMeshOrder() const;
/*!
* \brief sort submeshes according to stored mesh order
* \param theListToSort in out list to be sorted
* \return FALSE if nothing sorted
*/
bool SortByMeshOrder(std::list<SMESH_subMesh*>& theListToSort) const;
//
ostream& Dump(ostream & save);
private:
void fillAncestorsMap(const TopoDS_Shape& theShape);
std::list<SMESH_subMesh*> getAncestorsSubMeshes
(const TopoDS_Shape& theSubShape) const;
protected:
int _id; // id given by creator (unique within the creator instance)
int _studyId;
@ -274,6 +292,8 @@ protected:
TopTools_IndexedDataMapOfShapeListOfShape _mapAncestors;
TListOfListOfInt _mySubMeshOrder;
protected:
SMESH_Mesh() {};
SMESH_Mesh(const SMESH_Mesh&) {};

View File

@ -8975,6 +8975,7 @@ bool SMESH_MeshEditor::Make2DMeshFrom3D()
{
const SMDS_MeshVolume* volume = vIt->next();
SMDS_VolumeTool vTool( volume );
vTool.SetExternalNormal();
const bool isPoly = volume->IsPoly();
const bool isQuad = volume->IsQuadratic();
for ( int iface = 0, n = vTool.NbFaces(); iface < n; iface++ )
@ -8984,24 +8985,12 @@ bool SMESH_MeshEditor::Make2DMeshFrom3D()
vector<const SMDS_MeshNode *> nodes;
int nbFaceNodes = vTool.NbFaceNodes(iface);
const SMDS_MeshNode** faceNodes = vTool.GetFaceNodes(iface);
if (vTool.IsFaceExternal(iface))
{
int inode = 0;
for ( ; inode < nbFaceNodes; inode += isQuad ? 2 : 1)
nodes.push_back(faceNodes[inode]);
if (isQuad)
for ( inode = 1; inode < nbFaceNodes; inode += 2)
nodes.push_back(faceNodes[inode]);
}
else
{
int inode = nbFaceNodes-1;
for ( ; inode >=0; inode -= isQuad ? 2 : 1)
nodes.push_back(faceNodes[inode]);
if (isQuad)
for ( inode = nbFaceNodes-2; inode >=0; inode -= 2)
nodes.push_back(faceNodes[inode]);
}
// add new face based on volume nodes
if (aMesh->FindFace( nodes ) )

View File

@ -2191,3 +2191,29 @@ SMESH_subMeshIteratorPtr SMESH_subMesh::getDependsOnIterator(const bool includeS
( new _Iterator( new SMDS_mapIterator<TMap>( DependsOn() ), prepend, append ));
}
}
//================================================================================
/*!
* \brief Find common submeshes (based on shared subshapes with other
* \param theOther submesh to check
* \param theSetOfCommon set of common submesh
*/
//================================================================================
bool SMESH_subMesh::FindIntersection(const SMESH_subMesh* theOther,
std::set<const SMESH_subMesh*>& theSetOfCommon ) const
{
int oldNb = theSetOfCommon.size();
// check main submeshes
const map <int, SMESH_subMesh*>::const_iterator otherEnd = theOther->_mapDepend.end();
if ( theOther->_mapDepend.find(this->GetId()) != otherEnd )
theSetOfCommon.insert( this );
if ( _mapDepend.find(theOther->GetId()) != _mapDepend.end() )
theSetOfCommon.insert( theOther );
// check common submeshes
map <int, SMESH_subMesh*>::const_iterator mapIt = _mapDepend.begin();
for( ; mapIt != _mapDepend.end(); mapIt++ )
if ( theOther->_mapDepend.find((*mapIt).first) != otherEnd )
theSetOfCommon.insert( (*mapIt).second );
return oldNb < theSetOfCommon.size();
}

View File

@ -228,6 +228,15 @@ public:
bool IsAlwaysComputed() { return _alwaysComputed; }
/*!
* \brief Find common submeshes (based on shared subshapes with other
* \param theOther submesh to check
* \param theCommonIds set of common submesh IDs
* NOTE: this method does not cleat set before collect common IDs
*/
bool FindIntersection( const SMESH_subMesh * theOther,
std::set<const SMESH_subMesh*>& theSetOfCommon ) const;
protected:
// ==================================================================
void InsertDependence(const TopoDS_Shape aSubShape);

View File

@ -93,6 +93,8 @@ salomeinclude_HEADERS = \
SMESHGUI_MeshInfosBox.h \
SMESHGUI_Make2DFrom3DOp.h \
SMESHGUI_FindElemByPointDlg.h \
SMESHGUI_MeshOrderDlg.h \
SMESHGUI_MeshOrderOp.h \
SMESH_SMESHGUI.hxx
# Libraries targets
@ -162,7 +164,9 @@ dist_libSMESH_la_SOURCES = \
SMESHGUI_GroupOnShapeDlg.cxx \
SMESHGUI_FileInfoDlg.cxx \
SMESHGUI_MeshInfosBox.cxx \
SMESHGUI_Make2DFrom3DOp.cxx
SMESHGUI_Make2DFrom3DOp.cxx \
SMESHGUI_MeshOrderDlg.cxx \
SMESHGUI_MeshOrderOp.cxx
MOC_FILES = \
SMESHGUI_moc.cxx \
@ -218,7 +222,9 @@ MOC_FILES = \
SMESHGUI_MeshInfosBox_moc.cxx \
SMESHGUI_Make2DFrom3DOp_moc.cxx \
SMESHGUI_FindElemByPointDlg.cxx \
SMESHGUI_FindElemByPointDlg_moc.cxx
SMESHGUI_FindElemByPointDlg_moc.cxx \
SMESHGUI_MeshOrderDlg_moc.cxx \
SMESHGUI_MeshOrderOp_moc.cxx
nodist_libSMESH_la_SOURCES= \
$(MOC_FILES)

View File

@ -49,6 +49,7 @@
#include "SMESHGUI_MakeNodeAtPointDlg.h"
#include "SMESHGUI_MeshInfosDlg.h"
#include "SMESHGUI_MeshOp.h"
#include "SMESHGUI_MeshOrderOp.h"
#include "SMESHGUI_MeshPatternDlg.h"
#include "SMESHGUI_MoveNodesDlg.h"
#include "SMESHGUI_MultiEditDlg.h"
@ -1627,6 +1628,7 @@ bool SMESHGUI::OnGUIEvent( int theCommandID )
case 701: // COMPUTE MESH
case 711: // PRECOMPUTE MESH
case 712: // EVALUATE MESH
case 713: // MESH ORDER
{
if (checkLock(aStudy)) break;
startOperation( theCommandID );
@ -2722,6 +2724,7 @@ void SMESHGUI::initialize( CAM_Application* app )
createSMESHAction( 710, "BUILD_COMPOUND", "ICON_BUILD_COMPOUND" );
createSMESHAction( 711, "PRECOMPUTE", "ICON_PRECOMPUTE" );
createSMESHAction( 712, "EVALUATE", "ICON_COMPUTE" );
createSMESHAction( 713, "MESH_ORDER", "ICON_COMPUTE" );
createSMESHAction( 806, "CREATE_GEO_GROUP","ICON_CREATE_GEO_GROUP" );
createSMESHAction( 801, "CREATE_GROUP", "ICON_CREATE_GROUP" );
createSMESHAction( 802, "CONSTRUCT_GROUP", "ICON_CONSTRUCT_GROUP" );
@ -2871,6 +2874,7 @@ void SMESHGUI::initialize( CAM_Application* app )
createMenu( 701, meshId, -1 );
createMenu( 711, meshId, -1 );
createMenu( 712, meshId, -1 );
createMenu( 713, meshId, -1 );
createMenu( separator(), meshId, -1 );
createMenu( 801, meshId, -1 );
createMenu( 806, meshId, -1 );
@ -2976,6 +2980,7 @@ void SMESHGUI::initialize( CAM_Application* app )
createTool( 701, meshTb );
createTool( 711, meshTb );
createTool( 712, meshTb );
createTool( 713, meshTb );
createTool( separator(), meshTb );
createTool( 801, meshTb );
createTool( 806, meshTb );
@ -3107,7 +3112,8 @@ void SMESHGUI::initialize( CAM_Application* app )
popupMgr()->insert( separator(), -1, 0 );
createPopupItem( 701, OB, mesh, "&& isComputable" ); // COMPUTE
createPopupItem( 711, OB, mesh, "&& isComputable && isPreComputable" ); // PRECOMPUTE
createPopupItem( 712, OB, mesh, "&& isComputable" ); // COMPUTE
createPopupItem( 712, OB, mesh, "&& isComputable" ); // EVALUATE
createPopupItem( 713, OB, mesh, "&& isComputable" ); // MESH ORDER
createPopupItem( 214, OB, mesh_group ); // UPDATE
createPopupItem( 900, OB, mesh_group ); // ADV_INFO
createPopupItem( 902, OB, mesh ); // STD_INFO
@ -3934,6 +3940,9 @@ LightApp_Operation* SMESHGUI::createOperation( const int id ) const
case 712: // Evaluate mesh
op = new SMESHGUI_EvaluateOp();
break;
case 713: // Evaluate mesh
op = new SMESHGUI_MeshOrderOp();
break;
case 806: // Create group on geom
op = new SMESHGUI_GroupOnShapeOp();
break;

View File

@ -32,6 +32,9 @@
#include "SMESHGUI_MeshInfosBox.h"
#include "SMESHGUI_HypothesesUtils.h"
#include "SMESHGUI_MeshEditPreview.h"
#include "SMESHGUI_MeshOrderOp.h"
#include "SMESHGUI_MeshOrderDlg.h"
#include "SMESH_ActorUtils.h"
#include <SMDS_SetIterator.hxx>
@ -1218,6 +1221,7 @@ LightApp_Dialog* SMESHGUI_ComputeOp::dlg() const
SMESHGUI_PrecomputeOp::SMESHGUI_PrecomputeOp()
: SMESHGUI_BaseComputeOp(),
myDlg( 0 ),
myOrderMgr( 0 ),
myActiveDlg( 0 ),
myPreviewDisplayer( 0 )
{
@ -1234,6 +1238,8 @@ SMESHGUI_PrecomputeOp::~SMESHGUI_PrecomputeOp()
{
delete myDlg;
myDlg = 0;
delete myOrderMgr;
myOrderMgr = 0;
myActiveDlg = 0;
if ( myPreviewDisplayer )
delete myPreviewDisplayer;
@ -1299,6 +1305,16 @@ void SMESHGUI_PrecomputeOp::startOperation()
if (myMesh->_is_nil())
return;
if (myDlg->getPreviewMode() == -1)
{
// nothing to preview
SUIT_MessageBox::warning(desktop(),
tr("SMESH_WRN_WARNING"),
tr("SMESH_WRN_NOTHING_PREVIEW"));
onCancel();
return;
}
// disconnect slot from preview dialog to have Apply from results of compute operation only
disconnect( myDlg, SIGNAL( dlgOk() ), this, SLOT( onOk() ) );
disconnect( myDlg, SIGNAL( dlgApply() ), this, SLOT( onApply() ) );
@ -1363,6 +1379,15 @@ void SMESHGUI_PrecomputeOp::initDialog()
modes.append( SMESH::DIM_1D );
}
myOrderMgr = new SMESHGUI_MeshOrderMgr( myDlg->getMeshOrderBox() );
myOrderMgr->SetMesh( myMesh );
bool isOrder = myOrderMgr->GetMeshOrder(myPrevOrder);
myDlg->getMeshOrderBox()->setShown(isOrder);
if ( !isOrder ) {
delete myOrderMgr;
myOrderMgr = 0;
}
myDlg->setPreviewModes( modes );
}
@ -1423,6 +1448,8 @@ void SMESHGUI_PrecomputeOp::getAssignedAlgos(_PTR(SObject) theMesh,
void SMESHGUI_PrecomputeOp::onCompute()
{
myDlg->hide();
if (myOrderMgr && myOrderMgr->IsOrderChanged())
myOrderMgr->SetMeshOrder();
myMapShapeId.clear();
myActiveDlg = computeDlg();
computeMesh();
@ -1444,6 +1471,7 @@ void SMESHGUI_PrecomputeOp::onCancel()
return;
}
bool isRestoreOrder = false;
if ( myActiveDlg == myDlg && !myMesh->_is_nil() && myMapShapeId.count() )
{
// ask to remove already computed mesh elements
@ -1455,8 +1483,24 @@ void SMESHGUI_PrecomputeOp::onCancel()
QMap<int,int>::const_iterator it = myMapShapeId.constBegin();
for ( ; it != myMapShapeId.constEnd(); ++it )
myMesh->ClearSubMesh( *it );
isRestoreOrder = true;
}
}
// return previous mesh order
if (myOrderMgr && myOrderMgr->IsOrderChanged()) {
if (!isRestoreOrder)
isRestoreOrder =
(SUIT_MessageBox::question( desktop(), tr( "SMESH_WARNING" ),
tr( "SMESH_REJECT_MESH_ORDER" ),
tr( "SMESH_BUT_YES" ), tr( "SMESH_BUT_NO" ), 0, 1 ) == 0);
if (isRestoreOrder)
myOrderMgr->SetMeshOrder(myPrevOrder);
}
delete myOrderMgr;
myOrderMgr = 0;
myMapShapeId.clear();
SMESHGUI_BaseComputeOp::onCancel();
}
@ -1475,6 +1519,11 @@ void SMESHGUI_PrecomputeOp::onPreview()
_PTR(SObject) aMeshSObj = SMESH::FindSObject(myMesh);
if ( !aMeshSObj )
return;
// set modified submesh priority if any
if (myOrderMgr && myOrderMgr->IsOrderChanged())
myOrderMgr->SetMeshOrder();
// Compute preview of mesh,
// i.e. compute mesh till indicated dimension
int dim = myDlg->getPreviewMode();
@ -1579,7 +1628,8 @@ void SMESHGUI_PrecomputeOp::onPreview()
//================================================================================
SMESHGUI_PrecomputeDlg::SMESHGUI_PrecomputeDlg( QWidget* parent )
: SMESHGUI_Dialog( parent, false, false, OK | Cancel | Help )
: SMESHGUI_Dialog( parent, false, false, OK | Cancel | Help ),
myOrderBox(0)
{
setWindowTitle( tr( "CAPTION" ) );
@ -1588,6 +1638,9 @@ SMESHGUI_PrecomputeDlg::SMESHGUI_PrecomputeDlg( QWidget* parent )
QVBoxLayout* layout = new QVBoxLayout( main );
myOrderBox = new SMESHGUI_MeshOrderBox( main );
layout->addWidget(myOrderBox);
QFrame* frame = new QFrame( main );
layout->setMargin(0); layout->setSpacing(0);
layout->addWidget( frame );
@ -1644,6 +1697,17 @@ int SMESHGUI_PrecomputeDlg::getPreviewMode() const
return myPreviewMode->currentId();
}
//================================================================================
/*!
* \brief Returns current preview mesh mode
*/
//================================================================================
SMESHGUI_MeshOrderBox* SMESHGUI_PrecomputeDlg::getMeshOrderBox() const
{
return myOrderBox;
}
//================================================================================
/*!

View File

@ -36,6 +36,7 @@
// Qt includes
#include <QMap>
#include <QList>
#include <QPointer>
#include <QGroupBox>
@ -136,6 +137,8 @@ protected:
protected slots:
};
class SMESHGUI_MeshOrderMgr;
/*!
* \brief Operation to preview and compute a mesh and show computation errors
*/
@ -170,10 +173,16 @@ private slots:
void onCompute();
private:
//! private fields
QMap< int, int > myMapShapeId;
QPointer<LightApp_Dialog> myActiveDlg;
QPointer<SMESHGUI_PrecomputeDlg> myDlg;
SMESHGUI_MeshEditPreview* myPreviewDisplayer;
//! fields for mesh order
typedef QList<int> TListOfInt;
typedef QList<TListOfInt> TListOfListOfInt;
TListOfListOfInt myPrevOrder;
SMESHGUI_MeshOrderMgr* myOrderMgr;
};
/*!
@ -227,6 +236,8 @@ protected:
friend class SMESHGUI_PrecomputeOp;
};
class SMESHGUI_MeshOrderBox;
/*!
* \brief Dialog to preview and compute a mesh and show computation errors
*/
@ -242,10 +253,13 @@ public:
void setPreviewModes( const QList<int>& );
int getPreviewMode() const;
SMESHGUI_MeshOrderBox* getMeshOrderBox() const;
signals:
void preview();
private:
SMESHGUI_MeshOrderBox* myOrderBox;
QPushButton* myPreviewBtn;
QtxComboBox* myPreviewMode;
};

View File

@ -0,0 +1,332 @@
// Copyright (C) 2007-2008 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.
//
// 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 : SMESHGUI_MeshOrderDlg.cxx
// Author : Pavel TELKOV, Open CASCADE S.A.S.
// SMESH includes
//
#include "SMESHGUI_MeshOrderDlg.h"
// Qt includes
#include <Qt>
#include <QFrame>
#include <QLabel>
#include <QBoxLayout>
#include <QSpacerItem>
#include <QToolButton>
#include <QListWidget>
#include <QListWidgetItem>
#define SPACING 6
#define MARGIN 11
/*!
* Enumeartion of list widget item types (mesh name or separator)
*/
enum MeshOrderItemType { MeshItem = QListWidgetItem::UserType, SeparatorItem };
// =========================================================================================
/*!
* \brief Constructor
*/
// =========================================================================================
SMESHGUI_MeshOrderBox::SMESHGUI_MeshOrderBox(QWidget* theParent)
: QGroupBox( theParent ), myIsChanged( false ), myUpBtn(0), myDownBtn(0)
{
QHBoxLayout* hBoxLayout = new QHBoxLayout(this);
hBoxLayout->setMargin( MARGIN );
hBoxLayout->setSpacing( SPACING );
myMeshNames = new QListWidget(this);
myMeshNames->setSelectionMode(QAbstractItemView::SingleSelection);
myMeshNames->setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding ));
hBoxLayout->addWidget(myMeshNames);
QGroupBox* btnGrp = new QGroupBox(this);
hBoxLayout->addWidget(btnGrp);
myUpBtn = new QToolButton(btnGrp);
myDownBtn = new QToolButton(btnGrp);
myUpBtn-> setArrowType( Qt::UpArrow );
myDownBtn->setArrowType( Qt::DownArrow );
QVBoxLayout* vBoxLayout = new QVBoxLayout(btnGrp);
vBoxLayout->addSpacerItem( new QSpacerItem( 0, 0, QSizePolicy::Minimum, QSizePolicy::Expanding ) );
vBoxLayout->addWidget( myUpBtn );
vBoxLayout->addWidget( myDownBtn );
vBoxLayout->addSpacerItem( new QSpacerItem( 0, 0, QSizePolicy::Minimum, QSizePolicy::Expanding ) );
connect( myUpBtn, SIGNAL( clicked() ), this, SLOT( onMoveItem() ) );
connect( myDownBtn, SIGNAL( clicked() ), this, SLOT( onMoveItem() ) );
connect( myMeshNames, SIGNAL( itemSelectionChanged() ), this, SLOT( onSelectionChanged() ) );
onSelectionChanged();
}
// =========================================================================================
/*!
* \brief Destructor
*/
//=======================================================================
SMESHGUI_MeshOrderBox::~SMESHGUI_MeshOrderBox()
{
}
// =========================================================================================
/*!
* \brief add separator item
*/
// =========================================================================================
static void addSeparator( QListWidget* theList )
{
QListWidgetItem* item = new QListWidgetItem( theList, SeparatorItem );
QFrame* hline = new QFrame( theList );
hline->setFrameStyle( QFrame::HLine | QFrame::Sunken );
theList->addItem( item );
theList->setItemWidget( item, hline );
}
// =========================================================================================
/*!
* \brief add sub-mesh item
*/
// =========================================================================================
static void addMeshItem( QListWidget* theList,
const QString& theName,
const int theId )
{
QListWidgetItem* item = new QListWidgetItem( theName, theList, MeshItem );
item->setData( Qt::UserRole, theId );
theList->addItem( item );
}
// =========================================================================================
/*!
* \brief Clear submesh names and indeces
*/
// =========================================================================================
void SMESHGUI_MeshOrderBox::Clear()
{
myMeshNames->clear();
myIsChanged = false;
}
// =========================================================================================
/*!
* \brief Set submesh names and indeces
*/
// =========================================================================================
void SMESHGUI_MeshOrderBox::SetMeshes(const ListListName& theMeshNames,
const ListListId& theMeshIds)
{
Clear();
ListListName::const_iterator nLIt = theMeshNames.constBegin();
ListListId::const_iterator idLIt = theMeshIds.constBegin();
for ( ; nLIt != theMeshNames.constEnd(); ++nLIt, ++idLIt )
{
const QStringList& names = (*nLIt);
const QList<int>& ids = (*idLIt);
if ( myMeshNames->count() )
addSeparator( myMeshNames );
QStringList::const_iterator nameIt = names.constBegin();
QList<int>::const_iterator idIt = ids.constBegin();
for ( ; nameIt != names.constEnd(); ++nameIt, ++idIt )
addMeshItem( myMeshNames, *nameIt, *idIt );
}
}
// =========================================================================================
/*!
* \brief cehck that item exists and not a separator
*/
// =========================================================================================
static bool checkItem(QListWidgetItem* theItem)
{
return theItem && (int)theItem->type() != (int)SeparatorItem;
}
// =========================================================================================
/*!
* \brief Returns result (ordered by user) mesh names
*/
// =========================================================================================
ListListId SMESHGUI_MeshOrderBox::GetMeshIds() const
{
ListListId aLLIds;
aLLIds.append( QList<int>() );
for ( int i = 0, n = myMeshNames->count(); i < n; i++ )
{
QListWidgetItem* it = myMeshNames->item( i );
if (checkItem( it ))
aLLIds.last().append( it->data( Qt::UserRole ).toInt() );
else // separator before next list of mesh items
aLLIds.append( QList<int>() );
}
return aLLIds;
}
// =========================================================================================
/*!
* \brief Returns result (ordered by user) mesh indeces
*/
// =========================================================================================
ListListName SMESHGUI_MeshOrderBox::GetMeshNames() const
{
ListListName aLLNames;
aLLNames.append( QStringList() );
for ( int i = 0, n = myMeshNames->count(); i < n; i++ )
{
QListWidgetItem* it = myMeshNames->item( i );
if (checkItem( it ))
aLLNames.last().append( it->text() );
else // separator before next list of mesh items
aLLNames.append( QStringList() );
}
return aLLNames;
}
// =========================================================================================
/*!
* \brief update state of arrow buttons according to selection
*/
// =========================================================================================
void SMESHGUI_MeshOrderBox::onSelectionChanged()
{
bool isUp = false;
bool isDown = false;
QList<QListWidgetItem *> items = myMeshNames->selectedItems();
if ( !items.isEmpty() )
{
QListWidgetItem* selItem = (*(items.begin()));
if (checkItem(selItem))
{
const int rowId = myMeshNames->row( selItem );
isUp = checkItem( myMeshNames->item( rowId - 1 ) );
isDown = checkItem( myMeshNames->item( rowId + 1 ) );
}
}
myUpBtn-> setEnabled( isUp );
myDownBtn->setEnabled( isDown );
}
// =========================================================================================
/*!
* \brief move item according to clicked arrow button
*/
// =========================================================================================
void SMESHGUI_MeshOrderBox::onMoveItem()
{
moveItem( sender() == myUpBtn );
}
// =========================================================================================
/*!
* \brief move mesh in order up or down
*/
// =========================================================================================
void SMESHGUI_MeshOrderBox::moveItem(const bool theIsUp)
{
// move selected list item up or down
QList<QListWidgetItem *> items = myMeshNames->selectedItems();
if ( items.isEmpty() )
return;
QListWidgetItem * selItem = (*(items.begin()));
if (!checkItem(selItem))
return;
int rowId = myMeshNames->row( selItem );
if ( rowId == -1 )
return;
// move item in list widget
myIsChanged = true;
myMeshNames->takeItem( rowId );
myMeshNames->insertItem(theIsUp ? rowId-1 : rowId+1, selItem );
// restore selection and current status
selItem->setSelected( true );
myMeshNames->setCurrentItem( selItem );
}
// =========================================================================================
/*!
* \brief returns status is order changed by user
*/
// =========================================================================================
bool SMESHGUI_MeshOrderBox:: IsOrderChanged() const
{
return myIsChanged;
}
// =========================================================================================
/*!
* \brief Constructor
*/
// =========================================================================================
SMESHGUI_MeshOrderDlg::SMESHGUI_MeshOrderDlg(QWidget* theParent)
: SMESHGUI_Dialog( theParent, false, false, OK | Cancel | Help )
{
setWindowTitle( tr( "SMESH_MESHORDER_TITLE") );
QFrame* main = mainFrame();
QVBoxLayout* aDlgLay = new QVBoxLayout (main);
aDlgLay->setMargin( 0 );
aDlgLay->setSpacing( SPACING );
myBox = new SMESHGUI_MeshOrderBox( main );
aDlgLay->addWidget(myBox);
aDlgLay->setStretchFactor(main, 1);
}
// =========================================================================================
/*!
* \brief Destructor
*/
// =========================================================================================
SMESHGUI_MeshOrderDlg::~SMESHGUI_MeshOrderDlg()
{
}
// =========================================================================================
/*!
* \brief return Box widget to show mesh order
*/
// =========================================================================================
SMESHGUI_MeshOrderBox* SMESHGUI_MeshOrderDlg::GetMeshOrderBox() const
{
return myBox;
}

View File

@ -0,0 +1,114 @@
// Copyright (C) 2007-2009 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.
//
// 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 : SMESHGUI_MeshOrderDlg.h
// Author : Pavel TELKOV, Open CASCADE S.A.S.
//
#ifndef SMESHGUI_MeshOrderDlg_H
#define SMESHGUI_MeshOrderDlg_H
// SMESH includes
#include "SMESH_SMESHGUI.hxx"
#include "SMESHGUI_Dialog.h"
// Qt includes
#include <QGroupBox>
// IDL includes
#include <SALOMEconfig.h>
#include CORBA_SERVER_HEADER(SMESH_Mesh)
class QToolButton;
class QListWidget;
typedef QList<QStringList> ListListName;
typedef QList<int> ListId;
typedef QList<ListId> ListListId;
/*!
* \brief Reusable widget that shows and allows modify meshing order
*/
class SMESHGUI_EXPORT SMESHGUI_MeshOrderBox : public QGroupBox
{
Q_OBJECT
public:
/*! Public methods */
SMESHGUI_MeshOrderBox( QWidget* );
~SMESHGUI_MeshOrderBox();
//! Clear mesh box
void Clear();
//! Set mesh (submesh) names and indeces
void SetMeshes(const ListListName& theMeshNames,
const ListListId& theMeshIds);
//! returns status is order changed by user
bool IsOrderChanged() const;
//! Returns result (ordered by user) mesh names
ListListId GetMeshIds() const;
//! Returns result (ordered by user) mesh indeces
ListListName GetMeshNames() const;
private slots:
/*! Private slots */
//! update state of arrow buttons according to selection
void onSelectionChanged();
//! move item according to clicked arrow button
void onMoveItem();
private:
/*! Privatemethods */
//! move mesh in order up or down
void moveItem(const bool theIsUp);
private:
/*! Private fields */
bool myIsChanged;
QToolButton* myUpBtn;
QToolButton* myDownBtn;
QListWidget* myMeshNames;
};
/*!
* \brief Dialog contains mesh order box for modification operation
*/
class SMESHGUI_EXPORT SMESHGUI_MeshOrderDlg : public SMESHGUI_Dialog
{
Q_OBJECT
public:
/*! Public methods */
SMESHGUI_MeshOrderDlg( QWidget* );
~SMESHGUI_MeshOrderDlg();
SMESHGUI_MeshOrderBox* GetMeshOrderBox() const;
private:
/*! Private fields */
SMESHGUI_MeshOrderBox* myBox;
};
#endif // SMESHGUI_MeshOrderDlg_H

View File

@ -0,0 +1,325 @@
// Copyright (C) 2007-2009 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.
//
// 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 : SMESHGUI_MeshOrderOp.cxx
// Author : Pavel TELKOV, Open CASCADE S.A.S.
//
#include "SMESHGUI_MeshOrderOp.h"
#include "SMESHGUI.h"
#include "SMESHGUI_Utils.h"
#include "SMESHGUI_MeshUtils.h"
// SALOME GUI includes
#include <LightApp_SelectionMgr.h>
#include <SALOME_ListIO.hxx>
#include <SUIT_ResourceMgr.h>
#include <SUIT_OverrideCursor.h>
#include <SUIT_MessageBox.h>
#include <SUIT_Desktop.h>
// SALOME KERNEL includes
#include <SALOMEDS_SObject.hxx>
#include <SALOMEDSClient_SObject.hxx>
// STL includes
#include <set>
//================================================================================
/*!
* \brief Constructor
*/
//================================================================================
SMESHGUI_MeshOrderOp::SMESHGUI_MeshOrderOp()
: SMESHGUI_Operation(), myDlg(0), myMgr(0)
{
myDlg = new SMESHGUI_MeshOrderDlg( desktop() );
myHelpFileName = "constructing_meshes_page.html#mesh_order_anchor";
}
//================================================================================
/*!
* \brief Destructor
*/
//================================================================================
SMESHGUI_MeshOrderOp::~SMESHGUI_MeshOrderOp()
{
}
//================================================================================
/*!
* \brief Return operation dialog
*/
//================================================================================
LightApp_Dialog* SMESHGUI_MeshOrderOp::dlg() const
{
return myDlg;
}
//================================================================================
/*!
* \brief perform it's intention action: compute 2D mesh on 3D
*/
//================================================================================
void SMESHGUI_MeshOrderOp::startOperation()
{
SMESHGUI_Operation::startOperation();
if (myMgr)
myDlg->show();
}
//================================================================================
/*!
* \brief Init dialog and mesh order box
*/
//================================================================================
void SMESHGUI_MeshOrderOp::initDialog()
{
if (!myDlg )
return;
SMESH::SMESH_Mesh_var aMesh = SMESH::SMESH_Mesh::_nil();
// check selection
LightApp_SelectionMgr *Sel = selectionMgr();
SALOME_ListIO selected; Sel->selectedObjects( selected );
if (selected.Extent() == 1)
aMesh = SMESH::GetMeshByIO(selected.First());
if (aMesh->_is_nil()) {
SUIT_MessageBox::warning(desktop(),
tr("SMESH_WRN_WARNING"),
tr("SMESH_WRN_NO_AVAILABLE_DATA"));
onCancel();
return;
}
myMgr = new SMESHGUI_MeshOrderMgr( myDlg->GetMeshOrderBox() );
myMgr->SetMesh( aMesh );
if ( !myMgr->GetMeshOrder() ) {
SUIT_MessageBox::information(desktop(),
tr("SMESH_INFORMATION"),
tr("SMESH_NO_CONCURENT_MESH"));
onCancel();
return;
}
}
//================================================================================
/*!
* \brief Apply changes
*/
//================================================================================
bool SMESHGUI_MeshOrderOp::onApply()
{
SUIT_OverrideCursor aWaitCursor;
bool res = myMgr ? myMgr->SetMeshOrder() : false;
delete myMgr;
myMgr = 0;
return res;
}
//================================================================================
/*!
* \brief Apply changes
*/
//================================================================================
void SMESHGUI_MeshOrderOp::onCancel()
{
delete myMgr;
myMgr = 0;
abort();
}
//================================================================================
/*!
* \brief Constructor
*/
//================================================================================
SMESHGUI_MeshOrderMgr::SMESHGUI_MeshOrderMgr( SMESHGUI_MeshOrderBox* theBox )
: myBox( theBox )
{
myMesh = SMESH::SMESH_Mesh::_nil();
}
//================================================================================
/*!
* \brief Destructor
*/
//================================================================================
SMESHGUI_MeshOrderMgr::~SMESHGUI_MeshOrderMgr()
{
}
//================================================================================
/*!
* \brief Set root mesh object
*/
//================================================================================
void SMESHGUI_MeshOrderMgr::SetMesh(SMESH::SMESH_Mesh_var& theMesh)
{
myMesh = SMESH::SMESH_Mesh::_duplicate(theMesh);
_PTR(SObject) aMeshSObj = SMESH::FindSObject(theMesh);
if ( myBox && aMeshSObj )
myBox->setTitle( aMeshSObj->GetName().c_str() );
}
//================================================================================
/*!
* \brief Check for concurents between submesh objects
*/
//================================================================================
bool SMESHGUI_MeshOrderMgr::GetMeshOrder()
{
ListListId idListList;
return GetMeshOrder(idListList);
}
//================================================================================
/*!
* \brief Check for concurents between submesh objects
*/
//================================================================================
bool SMESHGUI_MeshOrderMgr::GetMeshOrder(ListListId& theIdListList)
{
if (!myBox || myMesh->_is_nil())
return false;
myBox->Clear();
SMESH::submesh_array_array_var meshOrder = myMesh->GetMeshOrder();
if ( !meshOrder.operator->() || !meshOrder->length() )
return false;
ListListName nameListList;
for ( int i = 0, n = meshOrder->length(); i < n; i++ )
{
QList<int> idList;
QStringList nameList;
const SMESH::submesh_array& aSMArray = meshOrder[i];
for ( int j = 0, jn = aSMArray.length(); j < jn; j++ )
{
const SMESH::SMESH_subMesh_var subMesh = aSMArray[j];
_PTR(SObject) aSubMeshSObj = SMESH::FindSObject(subMesh);
if ( !aSubMeshSObj )
continue;
idList.append(subMesh->GetId() );
nameList.append( QString(aSubMeshSObj->GetName().c_str()) );
}
theIdListList.append(idList);
nameListList.append(nameList);
}
myBox->SetMeshes(nameListList, theIdListList);
return !theIdListList.isEmpty();
}
//================================================================================
/*!
* \brief Returns status is order changed by user
*/
//================================================================================
bool SMESHGUI_MeshOrderMgr::IsOrderChanged() const
{
return myBox && myBox->IsOrderChanged();
}
//================================================================================
/*!
* \brief Store submesh priority order
*/
//================================================================================
bool SMESHGUI_MeshOrderMgr::SetMeshOrder()
{
return myBox ? SetMeshOrder(myBox->GetMeshIds()) : false;
}
//================================================================================
/*!
* \brief Store submesh priority order
*/
//================================================================================
bool SMESHGUI_MeshOrderMgr::SetMeshOrder( const ListListId& theListListIds )
{
if (theListListIds.isEmpty() || myMesh->_is_nil())
return false;
_PTR(Study) aStudy = SMESH::GetActiveStudyDocument();
_PTR(SObject) aMeshSObj = SMESH::FindSObject(myMesh);
if ( !aStudy || !aMeshSObj )
return false;
std::map<int, SMESH::SMESH_subMesh_var> mapOfSubMesh;
for (int i = SMESH::Tag_FirstSubMesh; i <= SMESH::Tag_LastSubMesh; i++) {
_PTR(SObject) aSubmeshRoot;
if ( !aMeshSObj->FindSubObject( i, aSubmeshRoot ) )
continue;
_PTR(ChildIterator) smIter = aStudy->NewChildIterator( aSubmeshRoot );
for ( ; smIter->More(); smIter->Next() ) {
_PTR(SObject) aSmObj = smIter->Value();
SMESH::SMESH_subMesh_var sm =
SMESH::SObjectToInterface<SMESH::SMESH_subMesh>( aSmObj );
mapOfSubMesh[ sm->GetId() ] = SMESH::SMESH_subMesh::_duplicate(sm);
}
}
// is it enought to set modifid attribute on root mesh objects only?
// it is seems that modifaction flag will be set on child submeshes
// automatically (see SMESH::ModifiedMesh for details)
SMESH::ModifiedMesh( aMeshSObj, false, false );
SMESH::submesh_array_array_var meshOrder = new SMESH::submesh_array_array();
meshOrder->length(theListListIds.count() );
ListListId::const_iterator it = theListListIds.constBegin();
for ( int i = 0; it != theListListIds.constEnd(); ++it ) {
const QList<int>& ids = *it;
SMESH::submesh_array_var subMeshList = new SMESH::submesh_array();
subMeshList->length( ids.count() );
QList<int>::const_iterator subIt = ids.constBegin();
for( int j = 0; subIt != ids.constEnd(); ++subIt )
if ( mapOfSubMesh.find( *subIt ) != mapOfSubMesh.end() )
subMeshList[ j++ ] = mapOfSubMesh[ *subIt ];
meshOrder[ i++ ] = subMeshList;
}
// update object browser
SMESHGUI::GetSMESHGUI()->updateObjBrowser( true, 0 );
return myMesh->SetMeshOrder(meshOrder);
}

View File

@ -0,0 +1,96 @@
// Copyright (C) 2007-2009 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.
//
// 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 : SMESHGUI_MeshOrderOp.h
// Author : Pavel TELKOV, Open CASCADE S.A.S.
//
#ifndef SMESHGUI_MeshOrderOp_H
#define SMESHGUI_MeshOrderOp_H
// SMESH includes
#include "SMESH_SMESHGUI.hxx"
#include "SMESHGUI_Operation.h"
#include "SMESHGUI_MeshOrderDlg.h"
// IDL includes
#include <SALOMEconfig.h>
#include CORBA_SERVER_HEADER(SMESH_Gen)
#include CORBA_SERVER_HEADER(SMESH_Mesh)
/*!
* \brief Operator to check and modify mesh computation submesh priority (order)
*/
class SMESHGUI_EXPORT SMESHGUI_MeshOrderMgr
{
public:
SMESHGUI_MeshOrderMgr( SMESHGUI_MeshOrderBox* );
virtual ~SMESHGUI_MeshOrderMgr();
//! Set root mesh object
void SetMesh( SMESH::SMESH_Mesh_var& theMesh );
//! Check for concurents between submesh objects
bool GetMeshOrder();
//! Check for concurents between submesh objects
bool GetMeshOrder( ListListId& theIds );
//! Store submesh priority order
bool SetMeshOrder();
//! Store given submesh priority order
bool SetMeshOrder( const ListListId& theIds );
//! Returns status is order changed by user
bool IsOrderChanged() const;
private:
SMESH::SMESH_Mesh_var myMesh;
SMESHGUI_MeshOrderBox* myBox;
};
/*!
* \brief Operator to check and modify mesh computation submesh priority (order)
*/
class SMESHGUI_EXPORT SMESHGUI_MeshOrderOp: public SMESHGUI_Operation
{
Q_OBJECT
public:
SMESHGUI_MeshOrderOp();
virtual ~SMESHGUI_MeshOrderOp();
protected:
virtual LightApp_Dialog* dlg() const;
virtual void startOperation();
//! sets the dialog widgets to state just after operation start
virtual void initDialog();
protected slots:
virtual bool onApply();
virtual void onCancel();
private:
SMESHGUI_MeshOrderDlg* myDlg;
SMESHGUI_MeshOrderMgr* myMgr;
};
#endif // SMESHGUI_MeshOrderOp_H

View File

@ -205,6 +205,10 @@
<source>MEN_2D_FROM_3D</source>
<translation>Create 2D mesh from 3D</translation>
</message>
<message>
<source>MEN_MESH_ORDER</source>
<translation>Change submesh priority</translation>
</message>
<message>
<source>MEN_CREATE_GROUP</source>
<translation>Create Group</translation>
@ -2063,6 +2067,10 @@ Consider saving your work before application crash</translation>
<source>STB_2D_FROM_3D</source>
<translation>Create 2D mesh from 3D</translation>
</message>
<message>
<source>STB_MESH_ORDER</source>
<translation>Change submesh priority</translation>
</message>
<message>
<source>STB_CREATE_GROUP</source>
<translation>Create Group</translation>
@ -2569,6 +2577,10 @@ Consider saving your work before application crash</translation>
<source>TOP_2D_FROM_3D</source>
<translation>Create 2D mesh from 3D</translation>
</message>
<message>
<source>TOP_MESH_ORDER</source>
<translation>Change submesh priority</translation>
</message>
<message>
<source>TOP_CREATE_GROUP</source>
<translation>Create Group</translation>
@ -3379,6 +3391,15 @@ Please, create VTK viewer and try again</translation>
created during preview operation.
Do you want to remove all this submeshes?</translation>
</message>
<message>
<source>SMESH_WRN_NOTHING_PREVIEW</source>
<translation>No mesh preview is available</translation>
</message>
<message>
<source>SMESH_REJECT_MESH_ORDER</source>
<translation>The submesh priority changed during preview operation.
Do you want to restore original submesh priority?</translation>
</message>
</context>
<context>
<name>SMESHGUI_ConvToQuadDlg</name>
@ -4899,4 +4920,18 @@ It is impossible to read point coordinates from file</translation>
<translation>Create Groups from Geometry</translation>
</message>
</context>
<context>
<name>SMESHGUI_MeshOrderDlg</name>
<message>
<source>SMESH_MESHORDER_TITLE</source>
<translation>Order of submesh in meshing process</translation>
</message>
</context>
<context>
<name>SMESHGUI_MeshOrderOp</name>
<message>
<source>SMESH_NO_CONCURENT_MESH</source>
<translation>No concurent submeshes detected</translation>
</message>
</context>
</TS>

View File

@ -261,6 +261,7 @@ Handle(_pyCommand) _pyGen::AddCommand( const TCollection_AsciiString& theCommand
Handle(_pySubMesh) subMesh = new _pySubMesh( aCommand );
myObjects.insert( make_pair( subMeshID, subMesh ));
}
id_mesh->second->Process( aCommand );
return aCommand;
}
@ -885,6 +886,34 @@ void _pyMesh::Process( const Handle(_pyCommand)& theCommand )
// remove hyp from myHypos
myHypos.remove( hyp );
}
// check for SubMesh order commands
else if ( theCommand->GetMethod() == "GetMeshOrder" ||
theCommand->GetMethod() == "SetMeshOrder" ) {
// In fact arguments and result values does not support complex containers
// such as list of list
// So, here we parse it manually
// GetMeshOrder
//for(int ind = 0, n = theCommand->GetNbResultValues();ind<n;ind++) {
// Handle(_pySubMesh) subMesh = theGen->FindSubMesh( theCommand->GetResultValue(ind) );
// SetMeshOrder
//for(int ind = 0, n = theCommand->GetNbArgs();ind<n;ind++) {
// Handle(_pySubMesh) subMesh = theGen->FindSubMesh( theCommand->GetArg(ind) );
const bool isArg = theCommand->GetMethod() == "SetMeshOrder";
const TCollection_AsciiString& cmdStr = theCommand->GetString();
int begPos = (/*isArg ? cmdStr.Search( "(" ) :*/ cmdStr.Search( "[" )) + 1;
int endPos = (isArg ? cmdStr.Search( ")" ) : cmdStr.Search( "=" )) - 1;
if ( begPos != -1 && begPos < endPos && endPos <= cmdStr.Length() ) {
TCollection_AsciiString aSubStr = cmdStr.SubString( begPos, endPos );
Standard_Integer index = 1;
TCollection_AsciiString anIDStr = aSubStr.Token("\t ,[]", index++);
while ( !anIDStr.IsEmpty() ) {
Handle(_pySubMesh) subMesh = theGen->FindSubMesh( anIDStr );
if ( !subMesh.IsNull() )
subMesh->Process( theCommand );
anIDStr = aSubStr.Token("\t ,[]", index++);
}
}
}
// add accessor method if necessary
else
{
@ -919,7 +948,7 @@ bool _pyMesh::NeedMeshAccess( const Handle(_pyCommand)& theCommand )
"GetNodeInverseElements","GetShapeID","GetShapeIDForElem","GetElemNbNodes",
"GetElemNode","IsMediumNode","IsMediumNodeOfAnyElem","ElemNbEdges","ElemNbFaces",
"IsPoly","IsQuadratic","BaryCenter","GetHypothesisList", "SetAutoColor", "GetAutoColor",
"Clear", "ConvertToStandalone"
"Clear", "ConvertToStandalone", "GetMeshOrder", "SetMeshOrder"
,"" }; // <- mark of end
sameMethods.Insert( names );
}

View File

@ -2722,6 +2722,40 @@ SALOMEDS::TMPFile* SMESH_Gen_i::Save( SALOMEDS::SComponent_ptr theComponent,
//if ( shapeRefFound )
//myWriter.AddAllSubMeshes();
// store submesh order if any
const TListOfListOfInt& theOrderIds = myLocMesh.GetMeshOrder();
if ( theOrderIds.size() ) {
char order_list[ 30 ];
strcpy( order_list, "Mesh Order" );
// count number of submesh ids
int nbIDs = 0;
TListOfListOfInt::const_iterator idIt = theOrderIds.begin();
for ( ; idIt != theOrderIds.end(); idIt++ )
nbIDs += (*idIt).size();
// number of values = number of IDs +
// number of lists (for separators) - 1
int* smIDs = new int [ nbIDs + theOrderIds.size() - 1 ];
idIt = theOrderIds.begin();
for ( int i = 0; idIt != theOrderIds.end(); idIt++ ) {
const TListOfInt& idList = *idIt;
if (idIt != theOrderIds.begin()) // not first list
smIDs[ i++ ] = -1/* *idList.size()*/; // separator between lists
// dump submesh ids from current list
TListOfInt::const_iterator id_smId = idList.begin();
for( ; id_smId != idList.end(); id_smId++ )
smIDs[ i++ ] = *id_smId;
}
// write HDF group
aSize[ 0 ] = nbIDs + theOrderIds.size() - 1;
aDataset = new HDFdataset( order_list, aTopGroup, HDF_INT32, aSize, 1 );
aDataset->CreateOnDisk();
aDataset->WriteOnDisk( smIDs );
aDataset->CloseOnDisk();
//
delete[] smIDs;
}
// groups root sub-branch
SALOMEDS::SObject_var myGroupsBranch;
for ( int i = GetNodeGroupsTag(); i <= GetVolumeGroupsTag(); i++ ) {
@ -2906,7 +2940,7 @@ SALOMEDS::TMPFile* SMESH_Gen_i::Save( SALOMEDS::SComponent_ptr theComponent,
aDataset->WriteOnDisk( smIDs );
aDataset->CloseOnDisk();
//
delete smIDs;
delete[] smIDs;
}
// Store node positions on sub-shapes (SMDS_Position):
@ -3494,7 +3528,6 @@ bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent,
}
}
}
}
}
}
@ -4117,6 +4150,24 @@ bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent,
aGroup->CloseOnDisk();
}
}
// read submeh order if any
if( aTopGroup->ExistInternalObject( "Mesh Order" ) ) {
aDataset = new HDFdataset( "Mesh Order", aTopGroup );
aDataset->OpenOnDisk();
size = aDataset->GetSize();
int* smIDs = new int[ size ];
aDataset->ReadFromDisk( smIDs );
aDataset->CloseOnDisk();
TListOfListOfInt anOrderIds;
anOrderIds.push_back( TListOfInt() );
for ( int i = 0; i < size; i++ )
if ( smIDs[ i ] < 0 ) // is separator
anOrderIds.push_back( TListOfInt() );
else
anOrderIds.back().push_back(smIDs[ i ]);
myNewMeshImpl->GetImpl().SetMeshOrder( anOrderIds );
}
}
// close mesh group
if(aTopGroup)

View File

@ -68,8 +68,11 @@
#include <TopExp.hxx>
#include <TopExp_Explorer.hxx>
#include <TopoDS_Compound.hxx>
#include <TopTools_MapOfShape.hxx>
#include <TopTools_MapIteratorOfMapOfShape.hxx>
// STL Includes
#include <algorithm>
#include <string>
#include <iostream>
#include <sstream>
@ -3457,3 +3460,424 @@ void SMESH_Mesh_i::CollectMeshInfo(const SMDS_ElemIteratorPtr theItr,
while (theItr->more())
theInfo[ theItr->next()->GetEntityType() ]++;
}
//=============================================================================
/*!
* \brief mapping of mesh dimension into shape type
*/
//=============================================================================
static TopAbs_ShapeEnum shapeTypeByDim(const int theDim)
{
TopAbs_ShapeEnum aType = TopAbs_SOLID;
switch ( theDim ) {
case 0: aType = TopAbs_VERTEX; break;
case 1: aType = TopAbs_EDGE; break;
case 2: aType = TopAbs_FACE; break;
case 3:
default:aType = TopAbs_SOLID; break;
}
return aType;
}
//=============================================================================
/*!
* \brief Internal structure to collect concurent submeshes
*/
//=============================================================================
class SMESH_DimHyp
{
public:
//! fileds
int _dim;
int _ownDim;
TopTools_MapOfShape _shapeMap;
SMESH_subMesh* _subMesh;
std::list<const SMESHDS_Hypothesis*> _hypothesises;
//! Constructors
SMESH_DimHyp(const SMESH_subMesh* theSubMesh,
const int theDim,
const TopoDS_Shape& theShape)
{
_subMesh = (SMESH_subMesh*)theSubMesh;
SetShape( theDim, theShape );
}
//! set shape
void SetShape(const int theDim,
const TopoDS_Shape& theShape)
{
_dim = theDim;
_ownDim = (int)SMESH_Gen::GetShapeDim(theShape);
if (_dim >= _ownDim)
_shapeMap.Add( theShape );
else {
TopExp_Explorer anExp( theShape, shapeTypeByDim(theDim) );
for( ; anExp.More(); anExp.Next() )
_shapeMap.Add( anExp.Current() );
}
}
//! Check sharing of sub shapes
static bool isShareSubShapes(const TopTools_MapOfShape& theToCheck,
const TopTools_MapOfShape& theToFind,
const TopAbs_ShapeEnum theType)
{
bool isShared = false;
TopTools_MapIteratorOfMapOfShape anItr( theToCheck );
for (; !isShared && anItr.More(); anItr.Next() ) {
const TopoDS_Shape aSubSh = anItr.Key();
// check for case when concurrent dimensions are same
isShared = theToFind.Contains( aSubSh );
// check for subshape with concurrent dimension
TopExp_Explorer anExp( aSubSh, theType );
for ( ; !isShared && anExp.More(); anExp.Next() )
isShared = theToFind.Contains( anExp.Current() );
}
return isShared;
}
//! check algorithms
static bool checkAlgo(const SMESHDS_Hypothesis* theA1,
const SMESHDS_Hypothesis* theA2)
{
if ( theA1->GetType() == SMESHDS_Hypothesis::PARAM_ALGO ||
theA2->GetType() == SMESHDS_Hypothesis::PARAM_ALGO )
return false; // one of the hypothesis is not algorithm
// check algorithm names (should be equal)
return strcmp( theA1->GetName(), theA2->GetName() ) == 0;
}
//! Check if subhape hypothesises is concurrent
bool IsConcurrent(const SMESH_DimHyp* theOther) const
{
if ( _subMesh == theOther->_subMesh )
return false; // same subshape - should not be
if ( (_ownDim == theOther->_dim || _dim == theOther->_ownDim ) &&
((_subMesh->GetSubMeshDS() && !(_subMesh->GetSubMeshDS()->IsComplexSubmesh())) ||
(theOther->_subMesh->GetSubMeshDS() && !(theOther->_subMesh->GetSubMeshDS()->IsComplexSubmesh())) ) )
return false; // no concurrence on shape and group (compound)
bool checkSubShape = ( _dim >= theOther->_dim )
? isShareSubShapes( _shapeMap, theOther->_shapeMap, shapeTypeByDim(theOther->_dim) )
: isShareSubShapes( theOther->_shapeMap, _shapeMap, shapeTypeByDim(_dim) ) ;
if ( !checkSubShape )
return false;
// check algorithms to be same
if (!checkAlgo( _hypothesises.front(), theOther->_hypothesises.front() ))
return true; // different algorithms
// check hypothesises for concurrence (skip first as algorithm)
int nbSame = 0;
// pointers should be same, becase it is referenes from mesh hypothesis partition
std::list <const SMESHDS_Hypothesis*>::const_iterator hypIt = _hypothesises.begin();
std::list <const SMESHDS_Hypothesis*>::const_iterator otheEndIt = theOther->_hypothesises.end();
for ( hypIt++ /*skip first as algo*/; hypIt != _hypothesises.end(); hypIt++ )
if ( find( theOther->_hypothesises.begin(), otheEndIt, *hypIt ) != otheEndIt )
nbSame++;
// the submeshes is concurrent if their algorithms has different parameters
return nbSame != theOther->_hypothesises.size() - 1;
}
}; // end of SMESH_DimHyp
typedef std::list<SMESH_DimHyp*> TDimHypList;
static void addDimHypInstance(const int theDim,
const TopoDS_Shape& theShape,
const SMESH_Algo* theAlgo,
const SMESH_subMesh* theSubMesh,
const std::list <const SMESHDS_Hypothesis*>& theHypList,
TDimHypList* theDimHypListArr )
{
TDimHypList& listOfdimHyp = theDimHypListArr[theDim];
if ( !listOfdimHyp.size() || listOfdimHyp.back()->_subMesh != theSubMesh ) {
SMESH_DimHyp* dimHyp = new SMESH_DimHyp( theSubMesh, theDim, theShape );
listOfdimHyp.push_back( dimHyp );
}
SMESH_DimHyp* dimHyp = listOfdimHyp.back();
dimHyp->_hypothesises.push_front(theAlgo);
std::list <const SMESHDS_Hypothesis*>::const_iterator hypIt = theHypList.begin();
for( ; hypIt != theHypList.end(); hypIt++ )
dimHyp->_hypothesises.push_back( *hypIt );
}
static void findConcurrents(const SMESH_DimHyp* theDimHyp,
const TDimHypList& theListOfDimHyp,
TListOfInt& theListOfConcurr )
{
TDimHypList::const_reverse_iterator rIt = theListOfDimHyp.rbegin();
for ( ; rIt != theListOfDimHyp.rend(); rIt++ ) {
const SMESH_DimHyp* curDimHyp = *rIt;
if ( curDimHyp == theDimHyp )
break; // meet own dimHyp pointer in same dimension
else if ( theDimHyp->IsConcurrent( curDimHyp ) )
if ( find( theListOfConcurr.begin(),
theListOfConcurr.end(),
curDimHyp->_subMesh->GetId() ) == theListOfConcurr.end() )
theListOfConcurr.push_back( curDimHyp->_subMesh->GetId() );
}
}
static void unionLists(TListOfInt& theListOfId,
TListOfListOfInt& theListOfListOfId,
const int theIndx )
{
TListOfListOfInt::iterator it = theListOfListOfId.begin();
for ( int i = 0; it != theListOfListOfId.end(); it++, i++ ) {
if ( i < theIndx )
continue; //skip already treated lists
// check is other list has any same submesh object
TListOfInt& otherListOfId = *it;
if ( find_first_of( theListOfId.begin(), theListOfId.end(),
otherListOfId.begin(), otherListOfId.end() ) == theListOfId.end() )
continue;
// union two lists (from source into target)
TListOfInt::iterator it2 = otherListOfId.begin();
for ( ; it2 != otherListOfId.end(); it2++ ) {
if ( find( theListOfId.begin(), theListOfId.end(), (*it2) ) == theListOfId.end() )
theListOfId.push_back(*it2);
}
// clear source list
otherListOfId.clear();
}
}
//! free memory allocated for dimension-hypothesis objects
static void removeDimHyps( TDimHypList* theArrOfList )
{
for (int i = 0; i < 4; i++ ) {
TDimHypList& listOfdimHyp = theArrOfList[i];
TDimHypList::const_iterator it = listOfdimHyp.begin();
for ( ; it != listOfdimHyp.end(); it++ )
delete (*it);
}
}
//=============================================================================
/*!
* \brief Return submesh objects list in meshing order
*/
//=============================================================================
SMESH::submesh_array_array* SMESH_Mesh_i::GetMeshOrder()
{
SMESH::submesh_array_array_var aResult = new SMESH::submesh_array_array();
SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
if ( !aMeshDS )
return aResult._retn();
::SMESH_Mesh& mesh = GetImpl();
TListOfListOfInt anOrder = mesh.GetMeshOrder();
if ( !anOrder.size() ) {
// collect submeshes detecting concurrent algorithms and hypothesises
TDimHypList* dimHypListArr = new TDimHypList[4]; // dimHyp list for each shape dimension
map<int, ::SMESH_subMesh*>::iterator i_sm = _mapSubMesh.begin();
for ( ; i_sm != _mapSubMesh.end(); i_sm++ ) {
::SMESH_subMesh* sm = (*i_sm).second;
// get shape of submesh
const TopoDS_Shape& aSubMeshShape = sm->GetSubShape();
// get list of assigned hypothesises
const std::list <const SMESHDS_Hypothesis*>& hypList = mesh.GetHypothesisList(aSubMeshShape);
std::list <const SMESHDS_Hypothesis*>::const_iterator hypIt = hypList.begin();
for( ; hypIt != hypList.end(); hypIt++ ) {
SMESH_Algo* anAlgo = 0;
const SMESH_Hypothesis* hyp = dynamic_cast<const SMESH_Hypothesis*>(*hypIt);
if ( hyp->GetType() != SMESHDS_Hypothesis::PARAM_ALGO )
anAlgo = (SMESH_Algo*)dynamic_cast<const SMESH_Algo*>(hyp);
else {
// try to find algorithm with helkp of subshapes
TopExp_Explorer anExp( aSubMeshShape, shapeTypeByDim(hyp->GetDim()) );
for ( ; !anAlgo && anExp.More(); anExp.Next() )
anAlgo = mesh.GetGen()->GetAlgo( mesh, anExp.Current() );
}
if (!anAlgo) // shopuld not be, but...
continue; // no assigned algorithm to current submesh
int dim = anAlgo->GetDim();
// create instance od dimension-hypiotheis for founded concurrent dimension and algorithm
for ( int j = anAlgo->NeedDescretBoundary() ? dim : 1, jn = dim; j <= jn; j++ )
addDimHypInstance( j, aSubMeshShape, anAlgo, sm, hypList, dimHypListArr );
}
} // end iterations on submesh
// iteartes on create dimension-hypothesises and check for concurrents
for ( int i = 0; i < 4; i++ ) {
const std::list<SMESH_DimHyp*>& listOfDimHyp = dimHypListArr[i];
// check for concurrents in own and other dimensions (step-by-step)
TDimHypList::const_iterator dhIt = listOfDimHyp.begin();
for ( ; dhIt != listOfDimHyp.end(); dhIt++ ) {
const SMESH_DimHyp* dimHyp = *dhIt;
TListOfInt listOfConcurr;
// looking for concurrents and collect into own list
for ( int j = i; j < 4; j++ )
findConcurrents( dimHyp, dimHypListArr[j], listOfConcurr );
// check if any concurrents found
if ( listOfConcurr.size() > 0 ) {
// add own submesh to list of concurrent
listOfConcurr.push_front( dimHyp->_subMesh->GetId() );
anOrder.push_back( listOfConcurr );
}
}
}
removeDimHyps(dimHypListArr);
delete[] dimHypListArr;
// now, minimise the number of concurrent groups
// Here we assume that lists of submhes can has same submesh
// in case of multi-dimension algorithms, as result
// list with common submesh have to be union into one list
int listIndx = 0;
TListOfListOfInt::iterator listIt = anOrder.begin();
for(; listIt != anOrder.end(); listIt++, listIndx++ )
unionLists( *listIt, anOrder, listIndx + 1 );
}
// convert submesh ids into interface instances
// and dump command into python
convertMeshOrder( anOrder, aResult, true );
return aResult._retn();
}
//=============================================================================
/*!
* \brief find common submeshes with given submesh
* \param theSubMeshList list of already collected submesh to check
* \param theSubMesh given submesh to intersect with other
* \param theCommonSubMeshes collected common submeshes
*/
//=============================================================================
static void findCommonSubMesh
(std::list<const SMESH_subMesh*>& theSubMeshList,
const SMESH_subMesh* theSubMesh,
std::set<const SMESH_subMesh*>& theCommon )
{
if ( !theSubMesh )
return;
std::list<const SMESH_subMesh*>::const_iterator it = theSubMeshList.begin();
for ( ; it != theSubMeshList.end(); it++ )
theSubMesh->FindIntersection( *it, theCommon );
theSubMeshList.push_back( theSubMesh );
//theCommon.insert( theSubMesh );
}
//=============================================================================
/*!
* \brief Set submesh object order
* \param theSubMeshArray submesh array order
*/
//=============================================================================
::CORBA::Boolean SMESH_Mesh_i::SetMeshOrder(const SMESH::submesh_array_array& theSubMeshArray)
{
bool res = false;
::SMESH_Mesh& mesh = GetImpl();
TPythonDump aPythonDump; // prevent dump of called methods
aPythonDump << "isDone = " << _this() << ".SetMeshOrder( [ ";
TListOfListOfInt subMeshOrder;
for ( int i = 0, n = theSubMeshArray.length(); i < n; i++ )
{
const SMESH::submesh_array& aSMArray = theSubMeshArray[i];
TListOfInt subMeshIds;
aPythonDump << "[ ";
// Collect subMeshes which should be clear
// do it list-by-list, because modification of submesh order
// take effect between concurrent submeshes only
std::set<const SMESH_subMesh*> subMeshToClear;
std::list<const SMESH_subMesh*> subMeshList;
for ( int j = 0, jn = aSMArray.length(); j < jn; j++ )
{
const SMESH::SMESH_subMesh_var subMesh = SMESH::SMESH_subMesh::_duplicate(aSMArray[j]);
if ( j > 0 )
aPythonDump << ", ";
aPythonDump << subMesh;
subMeshIds.push_back( subMesh->GetId() );
// detech common parts of submeshes
if ( _mapSubMesh.find(subMesh->GetId()) != _mapSubMesh.end() )
findCommonSubMesh( subMeshList, (*_mapSubMesh.find(subMesh->GetId())).second, subMeshToClear );
}
aPythonDump << " ]";
subMeshOrder.push_back( subMeshIds );
// clear collected submeshes
std::set<const SMESH_subMesh*>::iterator clrIt = subMeshToClear.begin();
for ( ; clrIt != subMeshToClear.end(); clrIt++ ) {
SMESH_subMesh* sm = (SMESH_subMesh*)*clrIt;
if ( sm )
sm->ComputeStateEngine( SMESH_subMesh::CLEAN );
// ClearSubMesh( *clrIt );
}
}
aPythonDump << " ])";
mesh.SetMeshOrder( subMeshOrder );
res = true;
return res;
}
//=============================================================================
/*!
* \brief Convert submesh ids into submesh interfaces
*/
//=============================================================================
void SMESH_Mesh_i::convertMeshOrder
(const TListOfListOfInt& theIdsOrder,
SMESH::submesh_array_array& theResOrder,
const bool theIsDump)
{
int nbSet = theIdsOrder.size();
TPythonDump aPythonDump; // prevent dump of called methods
if ( theIsDump )
aPythonDump << "[ ";
theResOrder.length(nbSet);
TListOfListOfInt::const_iterator it = theIdsOrder.begin();
int listIndx = 0;
for( ; it != theIdsOrder.end(); it++ ) {
// translate submesh identificators into submesh objects
// takeing into account real number of concurrent lists
const TListOfInt& aSubOrder = (*it);
if (!aSubOrder.size())
continue;
if ( theIsDump )
aPythonDump << "[ ";
// convert shape indeces into interfaces
SMESH::submesh_array_var aResSubSet = new SMESH::submesh_array();
aResSubSet->length(aSubOrder.size());
TListOfInt::const_iterator subIt = aSubOrder.begin();
for( int j = 0; subIt != aSubOrder.end(); subIt++ ) {
if ( _mapSubMeshIor.find(*subIt) == _mapSubMeshIor.end() )
continue;
SMESH::SMESH_subMesh_var subMesh =
SMESH::SMESH_subMesh::_duplicate( (*_mapSubMeshIor.find(*subIt)).second );
if ( theIsDump ) {
if ( j > 0 )
aPythonDump << ", ";
aPythonDump << subMesh;
}
aResSubSet[ j++ ] = subMesh;
}
if ( theIsDump )
aPythonDump << " ]";
theResOrder[ listIndx++ ] = aResSubSet;
}
// correct number of lists
theResOrder.length( listIndx );
if ( theIsDump ) {
// finilise python dump
aPythonDump << " ]";
aPythonDump << " = " << _this() << ".GetMeshOrder()";
}
}

View File

@ -501,6 +501,16 @@ public:
SMESH::long_array& theInfo);
/*!
* \brief Return submesh objects list in meshing order
*/
virtual SMESH::submesh_array_array* GetMeshOrder();
/*!
* \brief Set submesh object order
*/
virtual ::CORBA::Boolean SetMeshOrder(const SMESH::submesh_array_array& theSubMeshArray);
std::map<int, SMESH_subMesh_i*> _mapSubMesh_i; //NRI
std::map<int, ::SMESH_subMesh*> _mapSubMesh; //NRI
@ -510,6 +520,13 @@ private:
*/
void checkGroupNames();
/*!
* Convert submesh ids into submesh interfaces
*/
void convertMeshOrder(const TListOfListOfInt& theIdsOrder,
SMESH::submesh_array_array& theSubMeshOrder,
const bool theIsDump);
private:
static int myIdGenerator;

View File

@ -1201,6 +1201,18 @@ class Mesh:
pass
return ok
## Return submesh objects list in meshing order
# @return list of list of submesh objects
# @ingroup l2_construct
def GetMeshOrder(self):
return self.mesh.GetMeshOrder()
## Return submesh objects list in meshing order
# @return list of list of submesh objects
# @ingroup l2_construct
def SetMeshOrder(self, submeshes):
return self.mesh.SetMeshOrder(submeshes)
## Removes all nodes and elements
# @ingroup l2_construct
def Clear(self):