</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.
\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>
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
{
/*!
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
*/
if ( algo && !algo->NeedDescretBoundary() )
{
if ( algo->SupportSubmeshes() )
- smWithAlgoSupportingSubmeshes.push_back( smToCompute );
+ smWithAlgoSupportingSubmeshes.push_front( smToCompute );
else
{
smToCompute->ComputeStateEngine( SMESH_subMesh::COMPUTE );
}
}
}
+
+ // ------------------------------------------------------------
+ // 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 )
{
// ----------------------------------------------------------
// 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)
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);
}
}
}
+
+ // ------------------------------------------------------------
+ // 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;
// ----------------------------------------------------------
// 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);
std::map < int, SMESH_3D_Algo * >_map3D_Algo;
private:
-
+ //! private fields
int _localId; // unique Id of created objects, within SMESH_Gen entity
std::map < int, StudyContextStruct * >_mapStudyContext;
_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
{
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())
{
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"));
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
}
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;
}
}
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 )
{
{
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 )
{
aSubMesh = new SMESH_subMesh(index, this, _myMeshDS, aSubShape);
_mapSubMesh[index] = aSubMesh;
+ ClearMeshOrder();
}
return aSubMesh;
}
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;
+}
#include <TopoDS_Shape.hxx>
#include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
-#include <list>
#include <map>
+#include <list>
class SMESH_Gen;
class SMESHDS_Document;
class SMESH_HypoFilter;
class TopoDS_Solid;
+typedef std::list<int> TListOfInt;
+typedef std::list<TListOfInt> TListOfListOfInt;
+
class SMESH_EXPORT SMESH_Mesh
{
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)
std::map <int, SMESH_subMesh*> _mapSubMesh;
std::map <int, SMESH_Group*> _mapGroup;
SMESH_Gen * _gen;
-
+
bool _isAutoColor;
double _shapeDiagonal; //!< diagonal size of bounding box of shape to mesh
TopTools_IndexedDataMapOfShapeListOfShape _mapAncestors;
+ TListOfListOfInt _mySubMeshOrder;
+
protected:
SMESH_Mesh() {};
SMESH_Mesh(const SMESH_Mesh&) {};
{
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++ )
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)
+ 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]);
- 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 ) )
SMESHGUI_IdValidator.h \
SMESHGUI_MeshInfosBox.h \
SMESHGUI_Make2DFrom3DOp.h \
+ SMESHGUI_MeshOrderDlg.h \
+ SMESHGUI_MeshOrderOp.h \
SMESH_SMESHGUI.hxx
# Libraries targets
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 \
SMESHGUI_GroupOnShapeDlg_moc.cxx \
SMESHGUI_FileInfoDlg_moc.cxx \
SMESHGUI_MeshInfosBox_moc.cxx \
- SMESHGUI_Make2DFrom3DOp_moc.cxx
+ SMESHGUI_Make2DFrom3DOp_moc.cxx \
+ SMESHGUI_MeshOrderDlg_moc.cxx \
+ SMESHGUI_MeshOrderOp_moc.cxx
nodist_libSMESH_la_SOURCES= \
$(MOC_FILES)
#include "SMESHGUI_ComputeDlg.h"
#include "SMESHGUI_FileInfoDlg.h"
#include "SMESHGUI_Make2DFrom3DOp.h"
+#include "SMESHGUI_MeshOrderOp.h"
#include "SMESHGUI_Utils.h"
#include "SMESHGUI_MeshUtils.h"
case 701: // COMPUTE MESH
case 711: // PRECOMPUTE MESH
case 712: // EVALUATE MESH
+ case 713: // MESH ORDER
{
if (checkLock(aStudy)) break;
startOperation( theCommandID );
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" );
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 );
createTool( 701, meshTb );
createTool( 711, meshTb );
createTool( 712, meshTb );
+ createTool( 713, meshTb );
createTool( separator(), meshTb );
createTool( 801, meshTb );
createTool( 806, meshTb );
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
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;
#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>
int nbSel = selected.Extent();
if (nbSel != 1) {
SUIT_MessageBox::warning(desktop(),
- tr("SMESH_WRN_WARNING"),
- tr("SMESH_WRN_NO_AVAILABLE_DATA"));
+ tr("SMESH_WRN_WARNING"),
+ tr("SMESH_WRN_NO_AVAILABLE_DATA"));
onCancel();
return;
}
myMesh = SMESH::GetMeshByIO(myIObject);
if (myMesh->_is_nil()) {
SUIT_MessageBox::warning(desktop(),
- tr("SMESH_WRN_WARNING"),
- tr("SMESH_WRN_NO_AVAILABLE_DATA"));
+ tr("SMESH_WRN_WARNING"),
+ tr("SMESH_WRN_NO_AVAILABLE_DATA"));
onCancel();
return;
}
LightApp_SelectionMgr *Sel = selectionMgr();
if ( Sel )
{
- SALOME_ListIO selected;
- selected.Append( myIObject );
- Sel->setSelectedObjects( selected );
+ SALOME_ListIO selected;
+ selected.Append( myIObject );
+ Sel->setSelectedObjects( selected );
}
}
}
}
void SMESHGUI_BaseComputeOp::showComputeResult( const bool theMemoryLack,
- const bool theNoCompError,
- SMESH::compute_error_array_var& theCompErrors,
- const bool theNoHypoError,
- const QString& theHypErrors )
+ const bool theNoCompError,
+ SMESH::compute_error_array_var& theCompErrors,
+ const bool theNoHypoError,
+ const QString& theHypErrors )
{
bool hasShape = myMesh->HasShapeToMesh();
SMESHGUI_ComputeDlg* aCompDlg = computeDlg();
{
SMESH::ComputeError & err = theCompErrors[ row ];
- QString text = err.algoName.in();
- if ( !tbl->item( row, COL_ALGO ) ) tbl->setItem( row, COL_ALGO, new QTableWidgetItem( text ) );
- else tbl->item( row, COL_ALGO )->setText( text );
+ QString text = err.algoName.in();
+ if ( !tbl->item( row, COL_ALGO ) ) tbl->setItem( row, COL_ALGO, new QTableWidgetItem( text ) );
+ else tbl->item( row, COL_ALGO )->setText( text );
- text = SMESH::errorText( err.code, err.comment.in() );
- if ( !tbl->item( row, COL_ERROR ) ) tbl->setItem( row, COL_ERROR, new QTableWidgetItem( text ) );
- else tbl->item( row, COL_ERROR )->setText( text );
+ text = SMESH::errorText( err.code, err.comment.in() );
+ if ( !tbl->item( row, COL_ERROR ) ) tbl->setItem( row, COL_ERROR, new QTableWidgetItem( text ) );
+ else tbl->item( row, COL_ERROR )->setText( text );
- text = QString("%1").arg( err.subShapeID );
- if ( !tbl->item( row, COL_SHAPEID ) ) tbl->setItem( row, COL_SHAPEID, new QTableWidgetItem( text ) );
- else tbl->item( row, COL_SHAPEID )->setText( text );
+ text = QString("%1").arg( err.subShapeID );
+ if ( !tbl->item( row, COL_SHAPEID ) ) tbl->setItem( row, COL_SHAPEID, new QTableWidgetItem( text ) );
+ else tbl->item( row, COL_SHAPEID )->setText( text );
text = hasShape ? SMESH::shapeText( err.subShapeID, myMainShape ) : QString("");
- if ( !tbl->item( row, COL_SHAPE ) ) tbl->setItem( row, COL_SHAPE, new QTableWidgetItem( text ) );
- else tbl->item( row, COL_SHAPE )->setText( text );
+ if ( !tbl->item( row, COL_SHAPE ) ) tbl->setItem( row, COL_SHAPE, new QTableWidgetItem( text ) );
+ else tbl->item( row, COL_SHAPE )->setText( text );
text = ( !hasShape || SMESH::getSubShapeSO( err.subShapeID, myMainShape )) ? "PUBLISHED" : "";
- if ( !tbl->item( row, COL_PUBLISHED ) ) tbl->setItem( row, COL_PUBLISHED, new QTableWidgetItem( text ) );
- else tbl->item( row, COL_PUBLISHED )->setText( text ); // if text=="", "PUBLISH" button enabled
+ if ( !tbl->item( row, COL_PUBLISHED ) ) tbl->setItem( row, COL_PUBLISHED, new QTableWidgetItem( text ) );
+ else tbl->item( row, COL_PUBLISHED )->setText( text ); // if text=="", "PUBLISH" button enabled
text = err.hasBadMesh ? "hasBadMesh" : "";
- if ( !tbl->item( row, COL_BAD_MESH ) ) tbl->setItem( row, COL_BAD_MESH, new QTableWidgetItem( text ) );
- else tbl->item( row, COL_BAD_MESH )->setText( text );
+ if ( !tbl->item( row, COL_BAD_MESH ) ) tbl->setItem( row, COL_BAD_MESH, new QTableWidgetItem( text ) );
+ else tbl->item( row, COL_BAD_MESH )->setText( text );
if ( err.hasBadMesh ) hasBadMesh = true;
//tbl->item( row, COL_ERROR )->setWordWrap( true ); // VSR: TODO ???
SMESHGUI_PrecomputeOp::SMESHGUI_PrecomputeOp()
: SMESHGUI_BaseComputeOp(),
myDlg( 0 ),
+ myOrderMgr( 0 ),
myActiveDlg( 0 ),
myPreviewDisplayer( 0 )
{
{
delete myDlg;
myDlg = 0;
+ delete myOrderMgr;
+ myOrderMgr = 0;
myActiveDlg = 0;
if ( myPreviewDisplayer )
delete myPreviewDisplayer;
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() ) );
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 );
}
default: break;
}
if ( !algo->_is_nil() )
- theModeMap[ dim ] = 0;
+ theModeMap[ dim ] = 0;
}
}
}
void SMESHGUI_PrecomputeOp::onCompute()
{
myDlg->hide();
+ if (myOrderMgr && myOrderMgr->IsOrderChanged())
+ myOrderMgr->SetMeshOrder();
myMapShapeId.clear();
myActiveDlg = computeDlg();
computeMesh();
return;
}
+ bool isRestoreOrder = false;
if ( myActiveDlg == myDlg && !myMesh->_is_nil() && myMapShapeId.count() )
{
// ask to remove already computed mesh elements
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();
}
_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();
myPreviewDisplayer->SetData( previewRes );
// append shape indeces with computed mesh entities
for ( int i = 0, n = aShapesId->length(); i < n; i++ )
- myMapShapeId[ aShapesId[ i ] ] = 0;
+ myMapShapeId[ aShapesId[ i ] ] = 0;
}
else
myPreviewDisplayer->SetVisibility(false);
//================================================================================
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" ) );
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 );
return myPreviewMode->currentId();
}
+//================================================================================
+/*!
+ * \brief Returns current preview mesh mode
+*/
+//================================================================================
+
+SMESHGUI_MeshOrderBox* SMESHGUI_PrecomputeDlg::getMeshOrderBox() const
+{
+ return myOrderBox;
+}
+
//================================================================================
/*!
// SHOW RESULTS
if ( isShowResultDlg )
showEvaluateResult( aRes, memoryLack, noCompError, aCompErrors,
- noHypoError, aHypErrors);
+ noHypoError, aHypErrors);
}
void SMESHGUI_BaseComputeOp::showEvaluateResult(const SMESH::long_array& theRes,
- const bool theMemoryLack,
- const bool theNoCompError,
- SMESH::compute_error_array_var& theCompErrors,
- const bool theNoHypoError,
- const QString& theHypErrors)
+ const bool theMemoryLack,
+ const bool theNoCompError,
+ SMESH::compute_error_array_var& theCompErrors,
+ const bool theNoHypoError,
+ const QString& theHypErrors)
{
bool hasShape = myMesh->HasShapeToMesh();
SMESHGUI_ComputeDlg* aCompDlg = evaluateDlg();
{
SMESH::ComputeError & err = theCompErrors[ row ];
- QString text = err.algoName.in();
- if ( !tbl->item( row, COL_ALGO ) ) tbl->setItem( row, COL_ALGO, new QTableWidgetItem( text ) );
- else tbl->item( row, COL_ALGO )->setText( text );
+ QString text = err.algoName.in();
+ if ( !tbl->item( row, COL_ALGO ) ) tbl->setItem( row, COL_ALGO, new QTableWidgetItem( text ) );
+ else tbl->item( row, COL_ALGO )->setText( text );
- text = SMESH::errorText( err.code, err.comment.in() );
- if ( !tbl->item( row, COL_ERROR ) ) tbl->setItem( row, COL_ERROR, new QTableWidgetItem( text ) );
- else tbl->item( row, COL_ERROR )->setText( text );
+ text = SMESH::errorText( err.code, err.comment.in() );
+ if ( !tbl->item( row, COL_ERROR ) ) tbl->setItem( row, COL_ERROR, new QTableWidgetItem( text ) );
+ else tbl->item( row, COL_ERROR )->setText( text );
- text = QString("%1").arg( err.subShapeID );
- if ( !tbl->item( row, COL_SHAPEID ) ) tbl->setItem( row, COL_SHAPEID, new QTableWidgetItem( text ) );
- else tbl->item( row, COL_SHAPEID )->setText( text );
+ text = QString("%1").arg( err.subShapeID );
+ if ( !tbl->item( row, COL_SHAPEID ) ) tbl->setItem( row, COL_SHAPEID, new QTableWidgetItem( text ) );
+ else tbl->item( row, COL_SHAPEID )->setText( text );
text = hasShape ? SMESH::shapeText( err.subShapeID, myMainShape ) : QString("");
- if ( !tbl->item( row, COL_SHAPE ) ) tbl->setItem( row, COL_SHAPE, new QTableWidgetItem( text ) );
- else tbl->item( row, COL_SHAPE )->setText( text );
+ if ( !tbl->item( row, COL_SHAPE ) ) tbl->setItem( row, COL_SHAPE, new QTableWidgetItem( text ) );
+ else tbl->item( row, COL_SHAPE )->setText( text );
text = ( !hasShape || SMESH::getSubShapeSO( err.subShapeID, myMainShape )) ? "PUBLISHED" : "";
- if ( !tbl->item( row, COL_PUBLISHED ) ) tbl->setItem( row, COL_PUBLISHED, new QTableWidgetItem( text ) );
- else tbl->item( row, COL_PUBLISHED )->setText( text ); // if text=="", "PUBLISH" button enabled
+ if ( !tbl->item( row, COL_PUBLISHED ) ) tbl->setItem( row, COL_PUBLISHED, new QTableWidgetItem( text ) );
+ else tbl->item( row, COL_PUBLISHED )->setText( text ); // if text=="", "PUBLISH" button enabled
text = err.hasBadMesh ? "hasBadMesh" : "";
- if ( !tbl->item( row, COL_BAD_MESH ) ) tbl->setItem( row, COL_BAD_MESH, new QTableWidgetItem( text ) );
- else tbl->item( row, COL_BAD_MESH )->setText( text );
+ if ( !tbl->item( row, COL_BAD_MESH ) ) tbl->setItem( row, COL_BAD_MESH, new QTableWidgetItem( text ) );
+ else tbl->item( row, COL_BAD_MESH )->setText( text );
if ( err.hasBadMesh ) hasBadMesh = true;
//tbl->item( row, COL_ERROR )->setWordWrap( true ); // VSR: TODO ???
// Qt includes
#include <QMap>
+#include <QList>
#include <QPointer>
#include <QGroupBox>
protected slots:
};
+class SMESHGUI_MeshOrderMgr;
+
/*!
* \brief Operation to preview and compute a mesh and show computation errors
*/
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;
};
/*!
friend class SMESHGUI_PrecomputeOp;
};
+class SMESHGUI_MeshOrderBox;
+
/*!
* \brief Dialog to preview and compute a mesh and show computation errors
*/
void setPreviewModes( const QList<int>& );
int getPreviewMode() const;
+
+ SMESHGUI_MeshOrderBox* getMeshOrderBox() const;
signals:
void preview();
private:
+ SMESHGUI_MeshOrderBox* myOrderBox;
QPushButton* myPreviewBtn;
QtxComboBox* myPreviewMode;
};
--- /dev/null
+// 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;
+}
--- /dev/null
+// 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
--- /dev/null
+// 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);
+ }
+ }
+
+ 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;
+ }
+
+ return myMesh->SetMeshOrder(meshOrder);
+}
--- /dev/null
+// 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
<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>
<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>
<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>
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>
<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>
Handle(_pySubMesh) subMesh = new _pySubMesh( aCommand );
myObjects.insert( make_pair( subMeshID, subMesh ));
}
+
id_mesh->second->Process( aCommand );
return aCommand;
}
// 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
{
"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 );
}
#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>
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 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 << "[ ";
+ 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() );
+ }
+ aPythonDump << " ]";
+ subMeshOrder.push_back( subMeshIds );
+ }
+ 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++ ) {
+ 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()";
+ }
+}
public:
SMESH_Mesh_i( PortableServer::POA_ptr thePOA,
SMESH_Gen_i* myGen_i,
- CORBA::Long studyId );
+ CORBA::Long studyId );
virtual ~SMESH_Mesh_i();
static void CollectMeshInfo(const SMDS_ElemIteratorPtr theItr,
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
*/
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;
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):