Salome HOME
Imp 19925 - Mesh preview
authorptv <ptv@opencascade.com>
Mon, 1 Dec 2008 12:08:28 +0000 (12:08 +0000)
committerptv <ptv@opencascade.com>
Mon, 1 Dec 2008 12:08:28 +0000 (12:08 +0000)
15 files changed:
doc/salome/gui/SMESH/images/mesh_precompute.png
doc/salome/gui/SMESH/images/preview_mesh_1D.png [new file with mode: 0644]
doc/salome/gui/SMESH/images/preview_mesh_2D.png [new file with mode: 0644]
doc/salome/gui/SMESH/images/preview_tmp_data.png [new file with mode: 0644]
doc/salome/gui/SMESH/input/index.doc
doc/salome/gui/SMESH/input/preview_meshes.doc [new file with mode: 0644]
idl/SMESH_Gen.idl
idl/SMESH_Mesh.idl
src/SMESH/SMESH_Gen.cxx
src/SMESH/SMESH_Gen.hxx
src/SMESH/SMESH_Hypothesis.hxx
src/SMESH/SMESH_Mesh.cxx
src/SMESH/SMESH_Mesh.hxx
src/SMESH/SMESH_MeshEditor.cxx
src/SMESH/SMESH_MeshEditor.hxx

index 4d7bb3d46b6d1a595d98c2e2e43e1dfa9cd559c3..dd90498cf2807d1c51e06b16eda624dc42e69f6e 100644 (file)
Binary files a/doc/salome/gui/SMESH/images/mesh_precompute.png and b/doc/salome/gui/SMESH/images/mesh_precompute.png differ
diff --git a/doc/salome/gui/SMESH/images/preview_mesh_1D.png b/doc/salome/gui/SMESH/images/preview_mesh_1D.png
new file mode 100644 (file)
index 0000000..3922a19
Binary files /dev/null and b/doc/salome/gui/SMESH/images/preview_mesh_1D.png differ
diff --git a/doc/salome/gui/SMESH/images/preview_mesh_2D.png b/doc/salome/gui/SMESH/images/preview_mesh_2D.png
new file mode 100644 (file)
index 0000000..55ec7b8
Binary files /dev/null and b/doc/salome/gui/SMESH/images/preview_mesh_2D.png differ
diff --git a/doc/salome/gui/SMESH/images/preview_tmp_data.png b/doc/salome/gui/SMESH/images/preview_tmp_data.png
new file mode 100644 (file)
index 0000000..be1a125
Binary files /dev/null and b/doc/salome/gui/SMESH/images/preview_tmp_data.png differ
index 4f772a285884616e45f5a93d2a3e7e78eb5c561d..8cb09dbc414038691936f19f68eeaa418dde267a 100644 (file)
@@ -33,6 +33,7 @@
 <li>\ref constructing_submeshes_page</li>
 <li>\ref building_compounds_page</li>
 <li>\ref editing_meshes_page</li>
+<li>\ref preview_meshes_page</li>
 </ul>
 <li>\subpage viewing_meshes_page</li>
 <ul>
diff --git a/doc/salome/gui/SMESH/input/preview_meshes.doc b/doc/salome/gui/SMESH/input/preview_meshes.doc
new file mode 100644 (file)
index 0000000..92a4cca
--- /dev/null
@@ -0,0 +1,36 @@
+/*!
+
+\page preview_meshes_page Preview and Compute meshes
+
+Before whole mesh computation it is allowed to see the mesh preview.
+When mesh object is already created and all hypotheses assigned,
+select your mesh in the <b>Object Browser</b>. From the
+\b Mesh menu select \b Preview or click "Preview" button of the
+toolbar or activate "Preview" item from pop-up menu.
+
+\image html mesh_precompute.png
+<center><em>"Preview" button</em></center>
+
+The Mesh Preview dialog box appears. In this dialog box you can select
+preview mode <b>1D mesh</b> or <b>2D mesh</b> depending on assigned
+hypotheses to mesh. 
+
+The 1D mesh preview shows as nodes computed on geometry edges
+
+\image html preview_mesh_1D.png
+
+The 2D mesh preview shows edge mesh elements, computed on geometry faces
+
+\image html preview_mesh_2D.png
+
+Pressing <b>Compute</b> button leads to whole mesh computation
+process.
+During exit from Preview dialog box, the question about storage temporary
+created mesh elements appers:
+
+\image html preview_tmp_data.png
+
+Note, that computed temporary mesh elements can be reused during next
+mesh computation process.
+
+*/
index cad0d9f620614bac2f301d17014507adaef492e3..f12e67ae8d91013e3f7d7717d8ee22545edeae69 100644 (file)
@@ -221,6 +221,17 @@ module SMESH
                              in GEOM::GEOM_Object theSubObject )
       raises ( SALOME::SALOME_Exception );
 
+    /*!
+     * Calculate Mesh as preview till indicated dimension
+     * First, verify list of hypothesis associated with the subShape.
+     * Return mesh preview structure
+     */
+    MeshPreviewStruct Precompute( in SMESH_Mesh        theMesh, 
+                                 in GEOM::GEOM_Object theSubObject,
+                                 in Dimension         theDimension,
+                                 inout long_array    theShapesId )
+      raises ( SALOME::SALOME_Exception );
+
     /*!
      * Return errors of hypotheses definintion
      * algo_error_array is empty if everything is OK
index a0fff0fa9f0d7c112806eba0df89b4a4c9675797..76859da1461442f5a7e721369babc920f153ec86 100644 (file)
@@ -228,6 +228,12 @@ module SMESH
     void Clear()
       raises (SALOME::SALOME_Exception);
 
+    /*!
+     * Remove all nodes and elements of submesh
+     */
+    void ClearSubMesh(in long ShapeID)
+      raises (SALOME::SALOME_Exception);
+
     /*!
      * Get the subMesh object associated to a subShape. The subMesh object
      * gives access to nodes and elements IDs.
index e8d57f86c14672303afd0e64f873f44687137226..c86699a2a01eba19438caaba567ad4a06a0b6c03 100644 (file)
@@ -129,9 +129,11 @@ SMESH_Mesh* SMESH_Gen::CreateMesh(int theStudyId, bool theIsEmbeddedMode)
  */
 //=============================================================================
 
-bool SMESH_Gen::Compute(SMESH_Mesh &         aMesh,
-                        const TopoDS_Shape & aShape,
-                        const bool           anUpward)
+bool SMESH_Gen::Compute(SMESH_Mesh &          aMesh,
+                        const TopoDS_Shape &  aShape,
+                        const bool            anUpward,
+                       const ::MeshDimension aDim,
+                       TSetOfInt*            aShapesId)
 {
   MESSAGE("SMESH_Gen::Compute");
 
@@ -155,16 +157,22 @@ bool SMESH_Gen::Compute(SMESH_Mesh &         aMesh,
       SMESH_subMesh* smToCompute = smIt->next();
 
       // do not mesh vertices of a pseudo shape
-      if ( !aMesh.HasShapeToMesh() &&
-           smToCompute->GetSubShape().ShapeType() == TopAbs_VERTEX )
+      const TopAbs_ShapeEnum aShType = smToCompute->GetSubShape().ShapeType();
+      if ( !aMesh.HasShapeToMesh() && aShType == TopAbs_VERTEX )
         continue;
 
+      // check for preview dimension limitations
+      if ( aShapesId && GetShapeDim( aShType ) > (int)aDim )
+       continue;
+
       if (smToCompute->GetComputeState() == SMESH_subMesh::READY_TO_COMPUTE)
         smToCompute->ComputeStateEngine( SMESH_subMesh::COMPUTE );
 
       // we check all the submeshes here and detect if any of them failed to compute
       if (smToCompute->GetComputeState() == SMESH_subMesh::FAILED_TO_COMPUTE)
         ret = false;
+      else if ( aShapesId )
+       aShapesId->insert( smToCompute->GetId() );
     }
     return ret;
   }
@@ -184,7 +192,12 @@ bool SMESH_Gen::Compute(SMESH_Mesh &         aMesh,
         continue;
 
       const TopoDS_Shape& aSubShape = smToCompute->GetSubShape();
-      if ( GetShapeDim( aSubShape ) < 1 ) break;
+      const int aShapeDim = GetShapeDim( aSubShape );
+      if ( aShapeDim < 1 ) break;
+      
+      // check for preview dimension limitations
+      if ( aShapesId && aShapeDim > (int)aDim )
+       continue;
 
       SMESH_Algo* algo = GetAlgo( aMesh, aSubShape );
       if ( algo && !algo->NeedDescretBoundary() )
@@ -192,7 +205,11 @@ bool SMESH_Gen::Compute(SMESH_Mesh &         aMesh,
         if ( algo->SupportSubmeshes() )
           smWithAlgoSupportingSubmeshes.push_back( smToCompute );
         else
+       {
           smToCompute->ComputeStateEngine( SMESH_subMesh::COMPUTE );
+         if ( aShapesId )
+           aShapesId->insert( smToCompute->GetId() );
+       }
       }
     }
     // ------------------------------------------------------------
@@ -219,8 +236,14 @@ bool SMESH_Gen::Compute(SMESH_Mesh &         aMesh,
         SMESH_subMesh* smToCompute = smIt->next();
 
         const TopoDS_Shape& aSubShape = smToCompute->GetSubShape();
-        if ( aSubShape.ShapeType() == TopAbs_VERTEX ) continue;
-
+       const int aShapeDim = GetShapeDim( aSubShape );
+        //if ( aSubShape.ShapeType() == TopAbs_VERTEX ) continue;
+       if ( aShapeDim < 1 ) continue;
+
+       // check for preview dimension limitations
+       if ( aShapesId && GetShapeDim( aSubShape.ShapeType() ) > (int)aDim )
+         continue;
+       
         SMESH_HypoFilter filter( SMESH_HypoFilter::IsAlgo() );
         filter
           .And( SMESH_HypoFilter::IsApplicableTo( aSubShape ))
@@ -230,7 +253,7 @@ bool SMESH_Gen::Compute(SMESH_Mesh &         aMesh,
           SMESH_Hypothesis::Hypothesis_Status status;
           if ( subAlgo->CheckHypothesis( aMesh, aSubShape, status ))
             // mesh a lower smToCompute starting from vertices
-            Compute( aMesh, aSubShape, /*anUpward=*/true );
+            Compute( aMesh, aSubShape, /*anUpward=*/true, aDim, aShapesId );
         }
       }
     }
@@ -239,12 +262,21 @@ bool SMESH_Gen::Compute(SMESH_Mesh &         aMesh,
     // ----------------------------------------------------------
     for ( subIt = smWithAlgoSupportingSubmeshes.rbegin(); subIt != subEnd; ++subIt )
       if ( sm->GetComputeState() == SMESH_subMesh::READY_TO_COMPUTE)
+      {
+       const TopAbs_ShapeEnum aShType = sm->GetSubShape().ShapeType();
+       // check for preview dimension limitations
+       if ( aShapesId && GetShapeDim( aShType ) > (int)aDim )
+         continue;
+
         sm->ComputeStateEngine( SMESH_subMesh::COMPUTE );
+       if ( aShapesId )
+         aShapesId->insert( sm->GetId() );
+      }
 
     // -----------------------------------------------
     // mesh the rest subshapes starting from vertices
     // -----------------------------------------------
-    ret = Compute( aMesh, aShape, /*anUpward=*/true );
+    ret = Compute( aMesh, aShape, /*anUpward=*/true, aDim, aShapesId );
   }
 
   MESSAGE( "VSR - SMESH_Gen::Compute() finished, OK = " << ret);
@@ -708,14 +740,14 @@ int SMESH_Gen::GetShapeDim(const TopAbs_ShapeEnum & aShapeType)
   if ( dim.empty() )
   {
     dim.resize( TopAbs_SHAPE, -1 );
-    dim[ TopAbs_COMPOUND ]  = 3;
-    dim[ TopAbs_COMPSOLID ] = 3;
-    dim[ TopAbs_SOLID ]     = 3;
-    dim[ TopAbs_SHELL ]     = 3;
-    dim[ TopAbs_FACE  ]     = 2;
-    dim[ TopAbs_WIRE ]      = 1;
-    dim[ TopAbs_EDGE ]      = 1;
-    dim[ TopAbs_VERTEX ]    = 0;
+    dim[ TopAbs_COMPOUND ]  = MeshDim_3D;
+    dim[ TopAbs_COMPSOLID ] = MeshDim_3D;
+    dim[ TopAbs_SOLID ]     = MeshDim_3D;
+    dim[ TopAbs_SHELL ]     = MeshDim_3D;
+    dim[ TopAbs_FACE  ]     = MeshDim_2D;
+    dim[ TopAbs_WIRE ]      = MeshDim_1D;
+    dim[ TopAbs_EDGE ]      = MeshDim_1D;
+    dim[ TopAbs_VERTEX ]    = MeshDim_0D;
   }
   return dim[ aShapeType ];
 }
index ef90a40e44be6d0e441ad17dbbc88bdf40be5aee..a6a04436a0c10cf040d2e41ce0edf30c0702c73b 100644 (file)
@@ -45,6 +45,7 @@
 #include <TopoDS_Shape.hxx>
 
 #include <map>
+#include <list>
 
 class SMESHDS_Document;
 
@@ -57,6 +58,8 @@ typedef struct studyContextStruct
   SMESHDS_Document * myDocument;
 } StudyContextStruct;
 
+typedef std::set<int> TSetOfInt;
+
 class SMESH_EXPORT  SMESH_Gen
 {
  public:
@@ -69,11 +72,15 @@ class SMESH_EXPORT  SMESH_Gen
   /*!
    * \brief Computes aMesh on aShape 
    *  \param anUpward - compute from vertices up to more complex shape (internal usage)
+   *  \param aDim - upper level dimension of the mesh computation
+   *  \param aShapesId - list of shapes with computed mesh entities (elements or nodes)
    *  \retval bool - true if none submesh failed to compute
    */
-  bool Compute(::SMESH_Mesh &       aMesh,
-               const TopoDS_Shape & aShape,
-               const bool           anUpward=false);
+  bool Compute(::SMESH_Mesh &        aMesh,
+               const TopoDS_Shape &  aShape,
+               const bool            anUpward=false,
+              const ::MeshDimension aDim=::MeshDim_3D,
+              TSetOfInt*            aShapesId=0);
 
   bool CheckAlgoState(SMESH_Mesh& aMesh, const TopoDS_Shape& aShape);
   // notify on bad state of attached algos, return false
index a63ea921eb23099c1a7dc621f04969d04b0d8083..ea3f8c6b40e3863d33dc3ce21321c3c098a50f45 100644 (file)
@@ -37,6 +37,14 @@ class SMESH_Gen;
 class TopoDS_Shape;
 class SMESH_Mesh;
 
+enum MeshDimension // dimension of mesh
+{
+  MeshDim_0D,
+  MeshDim_1D,
+  MeshDim_2D,
+  MeshDim_3D
+};
+
 class SMESH_EXPORT SMESH_Hypothesis: public SMESHDS_Hypothesis
 {
 public:
index 23b16a7a394a145dd583dd4004be80a218395c0d..d8d8ea780598e550155d496a8b4113258277b8aa 100644 (file)
@@ -265,6 +265,32 @@ void SMESH_Mesh::Clear()
 //   }
 }
 
+//=======================================================================
+/*!
+ * \brief Remove all nodes and elements of indicated shape
+ */
+//=======================================================================
+
+void SMESH_Mesh::ClearSubMesh(const int theShapeId)
+{
+  // clear sub-meshes; get ready to re-compute as a side-effect 
+  if ( SMESH_subMesh *sm = GetSubMeshContaining( theShapeId ) )
+  {
+    SMESH_subMeshIteratorPtr smIt = sm->getDependsOnIterator(/*includeSelf=*/true,
+                                                            /*complexShapeFirst=*/false);
+    while ( smIt->more() )
+    {
+      sm = smIt->next();
+      TopAbs_ShapeEnum shapeType = sm->GetSubShape().ShapeType();      
+      if ( shapeType == TopAbs_VERTEX || shapeType < TopAbs_SOLID )
+       // all other shapes depends on vertices so they are already cleaned
+       sm->ComputeStateEngine( SMESH_subMesh::CLEAN );
+      // to recompute even if failed
+      sm->ComputeStateEngine( SMESH_subMesh::CHECK_COMPUTE_STATE );
+    }
+  }
+}
+
 //=======================================================================
 //function : UNVToMesh
 //purpose  : 
index 5fb1c0ab44fb89c78cfcf374454862fd54566abb..c07961fa8deb51b021a36bdf1fd51390c1577080 100644 (file)
@@ -87,6 +87,11 @@ public:
    */
   void Clear();
 
+  /*!
+   * \brief Remove all nodes and elements of indicated shape
+   */
+  void ClearSubMesh(const int theShapeId);
+
   int UNVToMesh(const char* theFileName);
   /*!
    * consult DriverMED_R_SMESHDS_Mesh::ReadStatus for returned value
index d52502f2589af6709f9c7fa7f99b1bccb2584e4e..14ea394da07e837d9c9386af91e7776485225452 100644 (file)
@@ -92,22 +92,6 @@ struct TNodeXYZ : public gp_XYZ {
   TNodeXYZ( const SMDS_MeshNode* n ):gp_XYZ( n->X(), n->Y(), n->Z() ) {}
 };
 
-typedef pair< const SMDS_MeshNode*, const SMDS_MeshNode* > NLink;
-
-//=======================================================================
-/*!
- * \brief A sorted pair of nodes
- */
-//=======================================================================
-
-struct TLink: public NLink
-{
-  TLink(const SMDS_MeshNode* n1, const SMDS_MeshNode* n2 ):NLink( n1, n2 )
-  { if ( n1->GetID() < n2->GetID() ) std::swap( first, second ); }
-  TLink(const NLink& link ):NLink( link )
-  { if ( first->GetID() < second->GetID() ) std::swap( first, second ); }
-};
-
 //=======================================================================
 //function : SMESH_MeshEditor
 //purpose  :
@@ -1460,10 +1444,10 @@ bool SMESH_MeshEditor::TriToQuad (TIDSortedElemSet &                   theElems,
   // 1. map of elements with their linkIDs
   // 2. map of linkIDs with their elements
 
-  map< TLink, list< const SMDS_MeshElement* > > mapLi_listEl;
-  map< TLink, list< const SMDS_MeshElement* > >::iterator itLE;
-  map< const SMDS_MeshElement*, set< TLink > >  mapEl_setLi;
-  map< const SMDS_MeshElement*, set< TLink > >::iterator itEL;
+  map< SMESH_TLink, list< const SMDS_MeshElement* > > mapLi_listEl;
+  map< SMESH_TLink, list< const SMDS_MeshElement* > >::iterator itLE;
+  map< const SMDS_MeshElement*, set< SMESH_TLink > >  mapEl_setLi;
+  map< const SMDS_MeshElement*, set< SMESH_TLink > >::iterator itEL;
 
   TIDSortedElemSet::iterator itElem;
   for ( itElem = theElems.begin(); itElem != theElems.end(); itElem++ ) {
@@ -1482,7 +1466,7 @@ bool SMESH_MeshEditor::TriToQuad (TIDSortedElemSet &                   theElems,
 
     // fill maps
     for ( i = 0; i < 3; i++ ) {
-      TLink link( aNodes[i], aNodes[i+1] );
+      SMESH_TLink link( aNodes[i], aNodes[i+1] );
       // check if elements sharing a link can be fused
       itLE = mapLi_listEl.find( link );
       if ( itLE != mapLi_listEl.end() ) {
@@ -1508,7 +1492,7 @@ bool SMESH_MeshEditor::TriToQuad (TIDSortedElemSet &                   theElems,
     int nbElems = (*itLE).second.size();
     if ( nbElems < 2  ) {
       const SMDS_MeshElement* elem = (*itLE).second.front();
-      TLink link = (*itLE).first;
+      SMESH_TLink link = (*itLE).first;
       mapEl_setLi[ elem ].erase( link );
       if ( mapEl_setLi[ elem ].empty() )
         mapEl_setLi.erase( elem );
@@ -1534,11 +1518,11 @@ bool SMESH_MeshEditor::TriToQuad (TIDSortedElemSet &                   theElems,
 
     // search elements to fuse starting from startElem or links of elements
     // fused earlyer - startLinks
-    list< TLink > startLinks;
+    list< SMESH_TLink > startLinks;
     while ( startElem || !startLinks.empty() ) {
       while ( !startElem && !startLinks.empty() ) {
         // Get an element to start, by a link
-        TLink linkId = startLinks.front();
+        SMESH_TLink linkId = startLinks.front();
         startLinks.pop_front();
         itLE = mapLi_listEl.find( linkId );
         if ( itLE != mapLi_listEl.end() ) {
@@ -1554,15 +1538,15 @@ bool SMESH_MeshEditor::TriToQuad (TIDSortedElemSet &                   theElems,
       if ( startElem ) {
         // Get candidates to be fused
         const SMDS_MeshElement *tr1 = startElem, *tr2 = 0, *tr3 = 0;
-        const TLink *link12, *link13;
+        const SMESH_TLink *link12, *link13;
         startElem = 0;
         ASSERT( mapEl_setLi.find( tr1 ) != mapEl_setLi.end() );
-        set< TLink >& setLi = mapEl_setLi[ tr1 ];
+        set< SMESH_TLink >& setLi = mapEl_setLi[ tr1 ];
         ASSERT( !setLi.empty() );
-        set< TLink >::iterator itLi;
+        set< SMESH_TLink >::iterator itLi;
         for ( itLi = setLi.begin(); itLi != setLi.end(); itLi++ )
         {
-          const TLink & link = (*itLi);
+          const SMESH_TLink & link = (*itLi);
           itLE = mapLi_listEl.find( link );
           if ( itLE == mapLi_listEl.end() )
             continue;
@@ -1583,10 +1567,10 @@ bool SMESH_MeshEditor::TriToQuad (TIDSortedElemSet &                   theElems,
           }
 
           // add other links of elem to list of links to re-start from
-          set< TLink >& links = mapEl_setLi[ elem ];
-          set< TLink >::iterator it;
+          set< SMESH_TLink >& links = mapEl_setLi[ elem ];
+          set< SMESH_TLink >::iterator it;
           for ( it = links.begin(); it != links.end(); it++ ) {
-            const TLink& link2 = (*it);
+            const SMESH_TLink& link2 = (*it);
             if ( link2 != link )
               startLinks.push_back( link2 );
           }
@@ -2443,9 +2427,8 @@ void SMESH_MeshEditor::Smooth (TIDSortedElemSet &          theElems,
     // fix nodes on mesh boundary
 
     if ( checkBoundaryNodes ) {
-      typedef pair<const SMDS_MeshNode*, const SMDS_MeshNode*> TLink;
-      map< TLink, int > linkNbMap; // how many times a link encounters in elemsOnFace
-      map< TLink, int >::iterator link_nb;
+      map< NLink, int > linkNbMap; // how many times a link encounters in elemsOnFace
+      map< NLink, int >::iterator link_nb;
       // put all elements links to linkNbMap
       list< const SMDS_MeshElement* >::iterator elemIt = elemsOnFace.begin();
       for ( ; elemIt != elemsOnFace.end(); ++elemIt ) {
@@ -2457,7 +2440,7 @@ void SMESH_MeshEditor::Smooth (TIDSortedElemSet &          theElems,
         const SMDS_MeshNode* curNode, *prevNode = elem->GetNode( nbn );
         for ( int iN = 0; iN < nbn; ++iN ) {
           curNode = elem->GetNode( iN );
-          TLink link;
+          NLink link;
           if ( curNode < prevNode ) link = make_pair( curNode , prevNode );
           else                      link = make_pair( prevNode , curNode );
           prevNode = curNode;
@@ -7541,8 +7524,8 @@ SMESH_MeshEditor::FindMatchingNodes(set<const SMDS_MeshElement*>& theSide1,
   if ( theSecondNode1 != theSecondNode2 )
     nReplaceMap.insert( make_pair( theSecondNode1, theSecondNode2 ));
 
-  set< TLink > linkSet; // set of nodes where order of nodes is ignored
-  linkSet.insert( TLink( theFirstNode1, theSecondNode1 ));
+  set< SMESH_TLink > linkSet; // set of nodes where order of nodes is ignored
+  linkSet.insert( SMESH_TLink( theFirstNode1, theSecondNode1 ));
 
   list< NLink > linkList[2];
   linkList[0].push_back( NLink( theFirstNode1, theSecondNode1 ));
@@ -7657,8 +7640,8 @@ SMESH_MeshEditor::FindMatchingNodes(set<const SMDS_MeshElement*>& theSide1,
       for ( int i = 0; i < nbN; i++ )
       {
         const SMDS_MeshNode* n2 = f0->GetNode( i );
-        pair< set< TLink >::iterator, bool > iter_isnew =
-          linkSet.insert( TLink( n1, n2 ));
+        pair< set< SMESH_TLink >::iterator, bool > iter_isnew =
+          linkSet.insert( SMESH_TLink( n1, n2 ));
         if ( !iter_isnew.second ) { // already in a set: no need to process
           linkSet.erase( iter_isnew.first );
         }
index 970dfc93086a85b4285e32ffa8d6504e158438f9..cb3ec69481d9c6fa34b2cbf27c2c6687306c81cc 100644 (file)
@@ -49,6 +49,24 @@ typedef std::map<const SMDS_MeshElement*,
                  std::list<const SMDS_MeshElement*> >        TElemOfElemListMap;
 typedef std::map<const SMDS_MeshNode*, const SMDS_MeshNode*> TNodeNodeMap;
 
+
+typedef pair< const SMDS_MeshNode*, const SMDS_MeshNode* > NLink;
+
+//=======================================================================
+/*!
+ * \brief A sorted pair of nodes
+ */
+//=======================================================================
+
+struct SMESH_TLink: public NLink
+{
+  SMESH_TLink(const SMDS_MeshNode* n1, const SMDS_MeshNode* n2 ):NLink( n1, n2 )
+  { if ( n1->GetID() < n2->GetID() ) std::swap( first, second ); }
+  SMESH_TLink(const NLink& link ):NLink( link )
+  { if ( first->GetID() < second->GetID() ) std::swap( first, second ); }
+};
+
+
 class SMDS_MeshFace;
 class SMDS_MeshNode;
 class gp_Ax1;