Salome HOME
IPAL52868: Confusing error message when computing an imported mesh w/o algo assigned
authoreap <eap@opencascade.com>
Mon, 5 Oct 2015 11:51:57 +0000 (14:51 +0300)
committereap <eap@opencascade.com>
Mon, 5 Oct 2015 11:51:57 +0000 (14:51 +0300)
IPAL52888: Pattern Mapping fails to load from a face just after study loading

19 files changed:
doc/salome/gui/SMESH/input/basic_meshing_algos.doc
doc/salome/gui/SMESH/input/pattern_mapping.doc
doc/salome/gui/SMESH/input/segments_around_vertex_algo.doc
src/SMESH/SMESH_Gen.cxx
src/SMESH/SMESH_MeshEditor.cxx
src/SMESH/SMESH_subMesh.cxx
src/SMESHGUI/SMESHGUI.cxx
src/SMESHGUI/SMESHGUI_ComputeDlg.cxx
src/SMESHGUI/SMESHGUI_RemoveNodesDlg.cxx
src/SMESHGUI/SMESHGUI_Selection.cxx
src/SMESHGUI/SMESHGUI_Selection.h
src/SMESHUtils/SMESH_MAT2d.cxx
src/SMESHUtils/SMESH_MAT2d.hxx
src/SMESH_I/SMESH_Filter_i.cxx
src/SMESH_I/SMESH_Gen_i.cxx
src/SMESH_I/SMESH_MeshEditor_i.cxx
src/SMESH_I/SMESH_Pattern_i.cxx
src/StdMeshers/StdMeshers_QuadFromMedialAxis_1D2D.cxx
src/StdMeshers/StdMeshers_Quadrangle_2D.cxx

index 090abd76f8dfd6117043c16c09b9c2f1a3624e27..080727462dc2113a6b5a95b6cab6f0b67a91641b 100644 (file)
@@ -14,10 +14,10 @@ of several dimensions.
 <li>For meshing of 1D entities (<b>edges</b>):</li>
 \anchor a1d_algos_anchor
 <ul>
 <li>For meshing of 1D entities (<b>edges</b>):</li>
 \anchor a1d_algos_anchor
 <ul>
-<li><em>Wire Discretization</em> meshing algorithm - splits an edge into a
+<li><b>Wire Discretization</b> meshing algorithm - splits an edge into a
 number of mesh segments following an 1D hypothesis.
 </li>
 number of mesh segments following an 1D hypothesis.
 </li>
-<li><em>Composite Side Discretization</em> algorithm - allows to apply a 1D
+<li><b>Composite Side Discretization</b> algorithm - allows to apply a 1D
   hypothesis to a whole side of a geometrical face even if it is
   composed of several edges provided that they form C1 curve in all
   faces of the main shape.</li>
   hypothesis to a whole side of a geometrical face even if it is
   composed of several edges provided that they form C1 curve in all
   faces of the main shape.</li>
@@ -26,7 +26,7 @@ number of mesh segments following an 1D hypothesis.
 <li>For meshing of 2D entities (<b>faces</b>):</li>
 
 <ul>
 <li>For meshing of 2D entities (<b>faces</b>):</li>
 
 <ul>
-<li><em>Triangle (Mefisto)</em> meshing algorithm - splits faces
+<li><b>Triangle (Mefisto)</b> meshing algorithm - splits faces
   into triangular elements.</li>
 <li>\subpage quad_ijk_algo_page "Quadrangle (Mapping)" meshing
   algorithm - splits faces into quadrangular elements.</li>
   into triangular elements.</li>
 <li>\subpage quad_ijk_algo_page "Quadrangle (Mapping)" meshing
   algorithm - splits faces into quadrangular elements.</li>
@@ -39,12 +39,12 @@ number of mesh segments following an 1D hypothesis.
 <li>For meshing of 3D entities (<b>solid objects</b>):</li>
 
 <ul>
 <li>For meshing of 3D entities (<b>solid objects</b>):</li>
 
 <ul>
-<li><em>Hexahedron (i,j,k)</em> meshing algorithm - solids are
+<li><b>Hexahedron (i,j,k)</b> meshing algorithm - solids are
   split into hexahedral elements thus forming a structured 3D
   mesh. The algorithm requires that 2D mesh generated on a solid could
   split into hexahedral elements thus forming a structured 3D
   mesh. The algorithm requires that 2D mesh generated on a solid could
-  be considered as a mesh of a box, i.e. there should be six nodes shared
-  by three quadrangles and the rest nodes should be shared by four
-  quadrangles.
+  be considered as a mesh of a box, i.e. there should be eight nodes
+  shared by three quadrangles and the rest nodes should be shared by
+  four quadrangles.
 \image html hexa_ijk_mesh.png "Structured mesh generated by Hexahedron (i,j,k) on a solid bound by 16 faces"
 </li>
 
 \image html hexa_ijk_mesh.png "Structured mesh generated by Hexahedron (i,j,k) on a solid bound by 16 faces"
 </li>
 
@@ -59,25 +59,25 @@ number of mesh segments following an 1D hypothesis.
 \image html image126.gif "Example of a hexahedral 3D mesh"
 </ul>
 
 \image html image126.gif "Example of a hexahedral 3D mesh"
 </ul>
 
-Some 3D meshing algorithms, such as Hexahedron(i,j,k) and some
-commercial ones, also can generate 3D meshes from 2D meshes, working
-without geometrical objects.
+Some 3D meshing algorithms, such as Hexahedron(i,j,k) also can
+generate 3D meshes from 2D meshes, working without geometrical
+objects.
 
 There is also a number of more specific algorithms:
 <ul>
 
 There is also a number of more specific algorithms:
 <ul>
-<li>\subpage prism_3d_algo_page "for meshing prismatic 3D shapes"</li>
-<li>\subpage quad_from_ma_algo_page "for meshing faces with sinuous borders"</li>
-<li> <em>Polygon per Face</em> meshing algorithm - generates one mesh
+<li>\subpage prism_3d_algo_page "for meshing prismatic 3D shapes with hexahedra and prisms"</li>
+<li>\subpage quad_from_ma_algo_page "for quadrangle meshing of faces with sinuous borders"</li>
+<li> <b>Polygon per Face</b> meshing algorithm - generates one mesh
   face (either a triangle, a quadrangle or a polygon) per a geometrical
   face using all nodes from the face boundary.</li>
 <li>\subpage projection_algos_page "for meshing by projection of another mesh"</li>
 <li>\subpage import_algos_page "for meshing by importing elements from another mesh"</li>
   face (either a triangle, a quadrangle or a polygon) per a geometrical
   face using all nodes from the face boundary.</li>
 <li>\subpage projection_algos_page "for meshing by projection of another mesh"</li>
 <li>\subpage import_algos_page "for meshing by importing elements from another mesh"</li>
-<li>\subpage radial_prism_algo_page "for meshing geometrical objects with cavities"</li>
-<li>\subpage radial_quadrangle_1D2D_algo_page "for meshing special faces (circles and parts of circles)"</li>
+<li>\subpage radial_prism_algo_page "for meshing 3D geometrical objects with cavities with hexahedra and prisms"</li>
+<li>\subpage radial_quadrangle_1D2D_algo_page "for quadrangle meshing of disks and parts of disks"</li>
 <li>\subpage use_existing_page "Use Edges to be Created Manually" and 
 <li>\subpage use_existing_page "Use Edges to be Created Manually" and 
-\ref use_existing_page "Use Faces to be Created Manually" algorithms can be
-used to create a 1D or a 2D mesh in a python script.</li>
-<li>\subpage segments_around_vertex_algo_page "for defining the local size of elements around a certain node"</li>
+  \ref use_existing_page "Use Faces to be Created Manually" algorithms can be
+  used to create a 1D or a 2D mesh in a python script.</li>
+<li>\subpage segments_around_vertex_algo_page "for defining the length of mesh segments around certain vertices"</li>
 </ul>
 
 \ref constructing_meshes_page "Constructing meshes" page describes in
 </ul>
 
 \ref constructing_meshes_page "Constructing meshes" page describes in
index 0fee46ccc870ebd42ea98aebc82fb54ac10f40f4..b42795e5d3eb2c6709c72f41f657a38a900a26a7 100644 (file)
@@ -149,7 +149,7 @@ Alternatively, it is possible to select <b>Refine selected mesh elements</b>
 check-box and apply the pattern to
 <ul>
   <li> One or several <b>Mesh volumes</b> instead of a geometric 3D object</li>
 check-box and apply the pattern to
 <ul>
   <li> One or several <b>Mesh volumes</b> instead of a geometric 3D object</li>
-  <li> and select two /b Nodes instead of vertices.</li> 
+  <li> and select two \b Nodes instead of vertices.</li> 
 </ul>
 Additionally it is possible to:
 <ul>
 </ul>
 Additionally it is possible to:
 <ul>
index f6250d2e509b0ddb13a1044d0eff9f82d0d8d972..ecd2e8aa9f91a13de0121db7a528cf1c8989fc3c 100644 (file)
@@ -3,15 +3,20 @@
 \page segments_around_vertex_algo_page Segments around Vertex
 
 \n <b>Segments around Vertex</b> algorithm is considered to be a 0D meshing
 \page segments_around_vertex_algo_page Segments around Vertex
 
 \n <b>Segments around Vertex</b> algorithm is considered to be a 0D meshing
-algorithm, but, of course, it doesn't mesh nodes. It allows to define
-the local size of the elements in the neighborhood of a certain
-node. If we choose an object of higher dimension, it applies to all
-its tops, i.e. corners of a box.  The 0D algorithm combines with the
-algorithms of higher dimensions, but it is not necessarily required
-for their successful implementation.
+algorithm, but, of course, it doesn't mesh vertices. It allows to define
+the local size of the segments in the neighborhood of a certain
+vertex. If we assign this algorithm to a geometrical object of higher
+dimension, it applies to all its vertices.
 
 
-This algorithm allows only one hypothesis.
+Length of segments near vertex is defined by <b> Length Near
+  Vertex </b> hypothesis.
+This hypothesis is used by \ref a1d_algos_anchor "Wire Discretization" or
+\ref a1d_algos_anchor "Composite Side Discretization" algorithms as
+follows: a geometrical edge is discretized according to a 1D
+  hypotheses and then nodes near vertices are modified to assure the
+  segment length required by <b> Length Near Vertex </b> hypothesis.
 
 \image html lengthnearvertex.png
 
 
 \image html lengthnearvertex.png
 
-*/
\ No newline at end of file
+
+*/
index 8fadef162a25872a02eecbf736d6c2c076b0ccc7..037acb584ed255d6d24f85c75aba670be8cd76c6 100644 (file)
@@ -943,7 +943,7 @@ bool SMESH_Gen::GetAlgoState(SMESH_Mesh&               theMesh,
   if ( !hasAlgo ) {
     ret = false;
     theErrors.push_back( TAlgoStateError() );
   if ( !hasAlgo ) {
     ret = false;
     theErrors.push_back( TAlgoStateError() );
-    theErrors.back().Set( SMESH_Hypothesis::HYP_MISSING, 1, true );
+    theErrors.back().Set( SMESH_Hypothesis::HYP_MISSING, theMesh.HasShapeToMesh() ? 1 : 3, true );
   }
 
   return ret;
   }
 
   return ret;
index bb114051dae41a68fbdf8bcd3249b1564d15f5b7..e34ccf0a39d43620449613e87145252fdedd60d6 100644 (file)
@@ -4816,7 +4816,7 @@ void SMESH_MeshEditor::sweepElement(const SMDS_MeshElement*               elem,
         else if(nbSame==1) {
           // ---> pyramid + pentahedron - can not be created since it is needed
           // additional middle node at the center of face
         else if(nbSame==1) {
           // ---> pyramid + pentahedron - can not be created since it is needed
           // additional middle node at the center of face
-          INFOS( " Sweep for face " << elem->GetID() << " can not be created" );
+          //INFOS( " Sweep for face " << elem->GetID() << " can not be created" );
           return;
         }
         else if( nbSame == 2 ) {
           return;
         }
         else if( nbSame == 2 ) {
@@ -11666,7 +11666,7 @@ bool SMESH_MeshEditor::DoubleNodesOnGroupBoundaries( const std::vector<TIDSorted
             }
           else
             {
             }
           else
             {
-              INFOS("Quadratic multiple joints not implemented");
+              //INFOS("Quadratic multiple joints not implemented");
               // TODO quadratic nodes
             }
         }
               // TODO quadratic nodes
             }
         }
index 6f46854f6233758a13dbe07edf622ad7479282a2..be6345c937f7697ebf36eb3284fc3be398e69f03 100644 (file)
@@ -1822,12 +1822,12 @@ bool SMESH_subMesh::Evaluate(MapShapeNbElems& aResMap)
   SMESH_Hypothesis::Hypothesis_Status hyp_status;
 
   algo = GetAlgo();
   SMESH_Hypothesis::Hypothesis_Status hyp_status;
 
   algo = GetAlgo();
-  if(algo && !aResMap.count(this) )
+  if( algo && !aResMap.count( this ))
   {
     ret = algo->CheckHypothesis((*_father), _subShape, hyp_status);
     if (!ret) return false;
 
   {
     ret = algo->CheckHypothesis((*_father), _subShape, hyp_status);
     if (!ret) return false;
 
-    if (_father->HasShapeToMesh() && algo->NeedDiscreteBoundary())
+    if (_father->HasShapeToMesh() && algo->NeedDiscreteBoundary() )
     {
       // check submeshes needed
       bool subMeshEvaluated = true;
     {
       // check submeshes needed
       bool subMeshEvaluated = true;
@@ -1845,8 +1845,23 @@ bool SMESH_subMesh::Evaluate(MapShapeNbElems& aResMap)
         return false;
     }
     _computeError = SMESH_ComputeError::New(COMPERR_OK,"",algo);
         return false;
     }
     _computeError = SMESH_ComputeError::New(COMPERR_OK,"",algo);
-    ret = algo->Evaluate((*_father), _subShape, aResMap);
 
 
+    if ( IsMeshComputed() )
+    {
+      vector<int> & nbEntities = aResMap[ this ];
+      nbEntities.resize( SMDSEntity_Last, 0 );
+      if ( SMESHDS_SubMesh* sm = GetSubMeshDS() )
+      {
+        nbEntities[ SMDSEntity_Node ] = sm->NbNodes();
+        SMDS_ElemIteratorPtr   elemIt = sm->GetElements();
+        while ( elemIt->more() )
+          nbEntities[ elemIt->next()->GetEntityType() ]++;
+      }
+    }
+    else
+    {
+      ret = algo->Evaluate((*_father), _subShape, aResMap);
+    }
     aResMap.insert( make_pair( this,vector<int>(0)));
   }
 
     aResMap.insert( make_pair( this,vector<int>(0)));
   }
 
index c7419274cd06084848ef6f9869edce716104d4b0..36a3c7d016468301b96e2ddd042f5a2d263ba449 100644 (file)
@@ -4336,35 +4336,35 @@ void SMESHGUI::initialize( CAM_Application* app )
     hasFacesOrVolumes("(({'Face'} in elemTypes) || ({'Volume'} in elemTypes)) ");
 
   createPopupItem( SMESHOp::OpFileInformation,      OB, mesh, "&& selcount=1 && isImported" );
     hasFacesOrVolumes("(({'Face'} in elemTypes) || ({'Volume'} in elemTypes)) ");
 
   createPopupItem( SMESHOp::OpFileInformation,      OB, mesh, "&& selcount=1 && isImported" );
-  createPopupItem( SMESHOp::OpCreateSubMesh,        OB, mesh, "&& isComputable");
-  createPopupItem( SMESHOp::OpEditMeshOrSubMesh,    OB, mesh, "&& isComputable");
-  createPopupItem( SMESHOp::OpEditMeshOrSubMesh,    OB, subMesh, "&& isComputable" );
+  createPopupItem( SMESHOp::OpCreateSubMesh,        OB, mesh, "&& hasGeomReference");
+  createPopupItem( SMESHOp::OpEditMeshOrSubMesh,    OB, mesh );
+  createPopupItem( SMESHOp::OpEditMeshOrSubMesh,    OB, subMesh, "&& hasGeomReference" );
   createPopupItem( SMESHOp::OpEditGroup,            OB, group );
   createPopupItem( SMESHOp::OpEditGeomGroupAsGroup, OB, group, "&& groupType != 'Group'" );
 
   popupMgr()->insert( separator(), -1, 0 );
   createPopupItem( SMESHOp::OpCompute,                OB, mesh, "&& isComputable" );
   createPopupItem( SMESHOp::OpEditGroup,            OB, group );
   createPopupItem( SMESHOp::OpEditGeomGroupAsGroup, OB, group, "&& groupType != 'Group'" );
 
   popupMgr()->insert( separator(), -1, 0 );
   createPopupItem( SMESHOp::OpCompute,                OB, mesh, "&& isComputable" );
-  createPopupItem( SMESHOp::OpPreCompute,             OB, mesh, "&& isComputable && isPreComputable" );
+  createPopupItem( SMESHOp::OpPreCompute,             OB, mesh, "&& isPreComputable" );
   createPopupItem( SMESHOp::OpEvaluate,               OB, mesh, "&& isComputable" );
   createPopupItem( SMESHOp::OpEvaluate,               OB, mesh, "&& isComputable" );
-  createPopupItem( SMESHOp::OpMeshOrder,              OB, mesh, "&& isComputable" );
+  createPopupItem( SMESHOp::OpMeshOrder,              OB, mesh, "&& isComputable && hasGeomReference" );
   createPopupItem( SMESHOp::OpUpdate,                 OB, mesh_part );
   createPopupItem( SMESHOp::OpMeshInformation,        OB, mesh_part );
   createPopupItem( SMESHOp::OpFindElementByPoint,     OB, mesh_group );
   createPopupItem( SMESHOp::OpOverallMeshQuality,     OB, mesh_part );
   popupMgr()->insert( separator(), -1, 0 );
   createPopupItem( SMESHOp::OpCreateGroup,            OB, mesh );
   createPopupItem( SMESHOp::OpUpdate,                 OB, mesh_part );
   createPopupItem( SMESHOp::OpMeshInformation,        OB, mesh_part );
   createPopupItem( SMESHOp::OpFindElementByPoint,     OB, mesh_group );
   createPopupItem( SMESHOp::OpOverallMeshQuality,     OB, mesh_part );
   popupMgr()->insert( separator(), -1, 0 );
   createPopupItem( SMESHOp::OpCreateGroup,            OB, mesh );
-  createPopupItem( SMESHOp::OpCreateGeometryGroup,    OB, mesh );
+  createPopupItem( SMESHOp::OpCreateGeometryGroup,    OB, mesh, "&& hasGeomReference" );
   createPopupItem( SMESHOp::OpConstructGroup,         OB, subMesh );
   popupMgr()->insert( separator(), -1, 0 );
   createPopupItem( SMESHOp::OpEditHypothesis,         OB, hypo);
   createPopupItem( SMESHOp::OpUnassign,               OB, hyp_alg );     // REMOVE HYPOTHESIS / ALGORITHMS
   popupMgr()->insert( separator(), -1, 0 );
   createPopupItem( SMESHOp::OpConstructGroup,         OB, subMesh );
   popupMgr()->insert( separator(), -1, 0 );
   createPopupItem( SMESHOp::OpEditHypothesis,         OB, hypo);
   createPopupItem( SMESHOp::OpUnassign,               OB, hyp_alg );     // REMOVE HYPOTHESIS / ALGORITHMS
   popupMgr()->insert( separator(), -1, 0 );
-  createPopupItem( SMESHOp::OpClearMesh,              OB, mesh );
-  popupMgr()->insert( separator(), -1, 0 );
   createPopupItem( SMESHOp::OpConvertMeshToQuadratic, OB, mesh + " " + subMesh );  // convert to quadratic
   createPopupItem( SMESHOp::OpCreateBoundaryElements, OB, mesh + " " + group,      // create 2D mesh from 3D
                    "&& dim>=2");
   popupMgr()->insert( separator(), -1, 0 );
   createPopupItem( SMESHOp::OpConvertMeshToQuadratic, OB, mesh + " " + subMesh );  // convert to quadratic
   createPopupItem( SMESHOp::OpCreateBoundaryElements, OB, mesh + " " + group,      // create 2D mesh from 3D
                    "&& dim>=2");
   popupMgr()->insert( separator(), -1, 0 );
+  createPopupItem( SMESHOp::OpClearMesh,              OB, mesh );
+  popupMgr()->insert( separator(), -1, 0 );
 
   QString only_one_non_empty = QString( " && %1=1 && numberOfNodes>0" ).arg( dc );
   QString multiple_non_empty = QString( " && %1>0 && numberOfNodes>0" ).arg( dc );
 
   QString only_one_non_empty = QString( " && %1=1 && numberOfNodes>0" ).arg( dc );
   QString multiple_non_empty = QString( " && %1>0 && numberOfNodes>0" ).arg( dc );
index 875eb675d5d59141c306af78227de61a8ebcd293..cdcc5d6e73f2b10862f38b0b7e65d1970e6dde5b 100644 (file)
@@ -1728,13 +1728,14 @@ void SMESHGUI_PrecomputeOp::initDialog()
 void SMESHGUI_PrecomputeOp::getAssignedAlgos(_PTR(SObject) theMesh,
                                              QMap<int,int>& theModeMap)
 {
 void SMESHGUI_PrecomputeOp::getAssignedAlgos(_PTR(SObject) theMesh,
                                              QMap<int,int>& theModeMap)
 {
-  _PTR(SObject)          aHypRoot;
+  if ( !theMesh ) return;
+  _PTR(SObject)          aHypFolder;
   _PTR(GenericAttribute) anAttr;
   int aPart = SMESH::Tag_RefOnAppliedAlgorithms;
   _PTR(GenericAttribute) anAttr;
   int aPart = SMESH::Tag_RefOnAppliedAlgorithms;
-  if ( theMesh && theMesh->FindSubObject( aPart, aHypRoot ) )
+  if ( theMesh->FindSubObject( aPart, aHypFolder ) )
   {
     _PTR(ChildIterator) anIter =
   {
     _PTR(ChildIterator) anIter =
-      SMESH::GetActiveStudyDocument()->NewChildIterator( aHypRoot );
+      SMESH::GetActiveStudyDocument()->NewChildIterator( aHypFolder );
     for ( ; anIter->More(); anIter->Next() )
     {
       _PTR(SObject) anObj = anIter->Value();
     for ( ; anIter->More(); anIter->Next() )
     {
       _PTR(SObject) anObj = anIter->Value();
@@ -1743,16 +1744,60 @@ void SMESHGUI_PrecomputeOp::getAssignedAlgos(_PTR(SObject) theMesh,
         anObj = aRefObj;
       else
         continue;
         anObj = aRefObj;
       else
         continue;
-      
+
       if ( anObj->FindAttribute( anAttr, "AttributeName" ) )
       {
         CORBA::Object_var aVar = _CAST(SObject,anObj)->GetObject();
         if ( CORBA::is_nil( aVar ) )
           continue;
       if ( anObj->FindAttribute( anAttr, "AttributeName" ) )
       {
         CORBA::Object_var aVar = _CAST(SObject,anObj)->GetObject();
         if ( CORBA::is_nil( aVar ) )
           continue;
-        
+
+        SMESH::SMESH_Algo_var algo;
+        for( int dim = SMESH::DIM_1D; dim <= SMESH::DIM_3D; dim++ )
+        {
+          switch(dim) {
+          case SMESH::DIM_1D: algo = SMESH::SMESH_1D_Algo::_narrow( aVar ); break;
+          case SMESH::DIM_2D: algo = SMESH::SMESH_2D_Algo::_narrow( aVar ); break;
+          case SMESH::DIM_3D: algo = SMESH::SMESH_3D_Algo::_narrow( aVar ); break;
+          default: break;
+          }
+          if ( !algo->_is_nil() )
+          {
+            theModeMap[ dim ] = 0;
+            if ( theModeMap.size() == 3 )
+              return;
+            break;
+          }
+        }
+      }
+    }
+  }
+
+  // check sub-meshes
+  for ( aPart = SMESH::Tag_SubMeshOnEdge; aPart < SMESH::Tag_LastSubMesh; ++aPart )
+  {
+    if ( !theMesh->FindSubObject( aPart, aHypFolder ))
+      continue;
+
+    _PTR(ChildIterator) anIter =
+      SMESH::GetActiveStudyDocument()->NewChildIterator( aHypFolder );
+    for ( anIter->InitEx(true); anIter->More(); anIter->Next() )
+    {
+      _PTR(SObject) anObj = anIter->Value();
+      _PTR(SObject) aRefObj;
+      if ( anObj->ReferencedObject( aRefObj ) )
+        anObj = aRefObj;
+      else
+        continue;
+
+      if ( anObj->FindAttribute( anAttr, "AttributeName" ))
+      {
+        CORBA::Object_var aVar = _CAST(SObject,anObj)->GetObject();
+        if ( CORBA::is_nil( aVar ) )
+          continue;
+
+        SMESH::SMESH_Algo_var algo;
         for( int dim = SMESH::DIM_1D; dim <= SMESH::DIM_3D; dim++ )
         {
         for( int dim = SMESH::DIM_1D; dim <= SMESH::DIM_3D; dim++ )
         {
-          SMESH::SMESH_Algo_var algo;
           switch(dim) {
           case SMESH::DIM_1D: algo = SMESH::SMESH_1D_Algo::_narrow( aVar ); break;
           case SMESH::DIM_2D: algo = SMESH::SMESH_2D_Algo::_narrow( aVar ); break;
           switch(dim) {
           case SMESH::DIM_1D: algo = SMESH::SMESH_1D_Algo::_narrow( aVar ); break;
           case SMESH::DIM_2D: algo = SMESH::SMESH_2D_Algo::_narrow( aVar ); break;
@@ -1760,7 +1805,12 @@ void SMESHGUI_PrecomputeOp::getAssignedAlgos(_PTR(SObject) theMesh,
           default: break;
           }
           if ( !algo->_is_nil() )
           default: break;
           }
           if ( !algo->_is_nil() )
+          {
             theModeMap[ dim ] = 0;
             theModeMap[ dim ] = 0;
+            if ( theModeMap.size() == 3 )
+              return;
+            break;
+          }
         }
       }
     }
         }
       }
     }
index d8f40a41c9cd80e354393037b362dc1587cc4223..5baaf4dc24aaa89b84dcafaeca93777a87498e71 100644 (file)
@@ -34,6 +34,7 @@
 #include "SMESHGUI_IdValidator.h"
 #include "SMESHGUI_FilterDlg.h"
 
 #include "SMESHGUI_IdValidator.h"
 #include "SMESHGUI_FilterDlg.h"
 
+#include <SMESH_TypeFilter.hxx>
 #include <SMESH_Actor.h>
 #include <SMDS_Mesh.hxx>
 
 #include <SMESH_Actor.h>
 #include <SMDS_Mesh.hxx>
 
@@ -208,14 +209,18 @@ void SMESHGUI_RemoveNodesDlg::Init()
   connect(mySMESHGUI, SIGNAL (SignalActivatedViewManager()), this, SLOT(onOpenView()));
   connect(mySMESHGUI, SIGNAL (SignalCloseView()),            this, SLOT(onCloseView()));
   connect(myEditCurrentArgument, SIGNAL(textChanged(const QString&)),
   connect(mySMESHGUI, SIGNAL (SignalActivatedViewManager()), this, SLOT(onOpenView()));
   connect(mySMESHGUI, SIGNAL (SignalCloseView()),            this, SLOT(onCloseView()));
   connect(myEditCurrentArgument, SIGNAL(textChanged(const QString&)),
-          SLOT(onTextChange(const QString&)));
-  
+          this,                  SLOT (onTextChange(const QString&)));
+
   SMESH::SetPointRepresentation(true);
   SMESH::SetPointRepresentation(true);
-  
+
+  mySelectionMgr->clearFilters();
+  mySelectionMgr->installFilter( new SMESH_TypeFilter( SMESH::IDSOURCE ));
+
   if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
     aViewWindow->SetSelectionMode(NodeSelection);
 
   if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
     aViewWindow->SetSelectionMode(NodeSelection);
 
-  SelectionIntoArgument();
+  //SelectionIntoArgument();
+  mySelectionMgr->setSelectedObjects( SALOME_ListIO() );
 }
 
 //=================================================================================
 }
 
 //=================================================================================
@@ -412,16 +417,16 @@ void SMESHGUI_RemoveNodesDlg::SelectionIntoArgument()
           myBusy = true;
           myEditCurrentArgument->setText(aString);
           myBusy = false;
           myBusy = true;
           myEditCurrentArgument->setText(aString);
           myBusy = false;
-          
+
           // OK
           // OK
-          
+
           myNbOkNodes = nbNodes;
         } // if (nbNodes > 0)
       } // if (myActor)
     } // if (!myMesh->_is_nil())
   } // if (nbSel == 1)
 
           myNbOkNodes = nbNodes;
         } // if (nbNodes > 0)
       } // if (myActor)
     } // if (!myMesh->_is_nil())
   } // if (nbSel == 1)
 
-  updateButtons();        
+  updateButtons();
 }
 
 //=================================================================================
 }
 
 //=================================================================================
@@ -474,6 +479,9 @@ void SMESHGUI_RemoveNodesDlg::ActivateThisDialog()
 
   mySMESHGUI->SetActiveDialogBox((QDialog*)this); // ??
 
 
   mySMESHGUI->SetActiveDialogBox((QDialog*)this); // ??
 
+  mySelectionMgr->clearFilters();
+  mySelectionMgr->installFilter( new SMESH_TypeFilter( SMESH::IDSOURCE ));
+
   SMESH::SetPointRepresentation(true);
   if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
     aViewWindow->SetSelectionMode(NodeSelection);
   SMESH::SetPointRepresentation(true);
   if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
     aViewWindow->SetSelectionMode(NodeSelection);
index 24719c916088ec0925a4eda145518e579eab2b47..3661fa85304ecae7834acfa364b28035977602ed 100644 (file)
@@ -128,7 +128,7 @@ QVariant SMESHGUI_Selection::parameter( const int ind, const QString& p ) const
   else if ( p=="displayMode" )          val = QVariant( displayMode( ind ) );
   else if ( p=="isComputable" )         val = QVariant( isComputable( ind ) );
   else if ( p=="isPreComputable" )      val = QVariant( isPreComputable( ind ) );
   else if ( p=="displayMode" )          val = QVariant( displayMode( ind ) );
   else if ( p=="isComputable" )         val = QVariant( isComputable( ind ) );
   else if ( p=="isPreComputable" )      val = QVariant( isPreComputable( ind ) );
-  else if ( p=="hasReference" )         val = QVariant( hasReference( ind ) );
+  else if ( p=="hasGeomReference" )     val = QVariant( hasGeomReference( ind ) );
   else if ( p=="isImported" )           val = QVariant( isImported( ind ) );
   else if ( p=="facesOrientationMode" ) val = QVariant( facesOrientationMode( ind ) );
   else if ( p=="groupType" )            val = QVariant( groupType( ind ) );
   else if ( p=="isImported" )           val = QVariant( isImported( ind ) );
   else if ( p=="facesOrientationMode" ) val = QVariant( facesOrientationMode( ind ) );
   else if ( p=="groupType" )            val = QVariant( groupType( ind ) );
@@ -492,62 +492,58 @@ int SMESHGUI_Selection::dim( int ind ) const
 
 //=======================================================================
 //function : isComputable
 
 //=======================================================================
 //function : isComputable
-//purpose  : 
+//purpose  : return true for a ready-to-compute mesh
 //=======================================================================
 
 QVariant SMESHGUI_Selection::isComputable( int ind ) const
 {
 //=======================================================================
 
 QVariant SMESHGUI_Selection::isComputable( int ind ) const
 {
-  if ( ind >= 0 && ind < myTypes.count() && myTypes[ind] != "Unknown" )
+  if ( ind >= 0 && ind < myTypes.count() && myTypes[ind] == "Mesh" )
   {
   {
+    QMap<int,int> modeMap;
     _PTR(SObject) so = SMESH::GetActiveStudyDocument()->FindObjectID( entry( ind ).toLatin1().data() );
     _PTR(SObject) so = SMESH::GetActiveStudyDocument()->FindObjectID( entry( ind ).toLatin1().data() );
-    CORBA::Object_var obj = SMESH::SObjectToObject( so, SMESH::GetActiveStudyDocument() );
-    if( !CORBA::is_nil( obj ) ) {
-      SMESH::SMESH_Mesh_var mesh = SMESH::SMESH_Mesh::_narrow( obj );
-      if ( !CORBA::is_nil( mesh ) ) {
-        if ( mesh->HasShapeToMesh() ) {
-          GEOM::GEOM_Object_var shape = SMESH::GetShapeOnMeshOrSubMesh( so );
-          return QVariant( !shape->_is_nil() );
-        }
-        else
-        {
-          return QVariant( mesh->NbFaces() !=0 );
-        }
-      }
-      else
-      {
-        GEOM::GEOM_Object_var shape = SMESH::GetShapeOnMeshOrSubMesh( so );
-        return QVariant( !shape->_is_nil() );
-      }
-    }
+    SMESHGUI_PrecomputeOp::getAssignedAlgos( so, modeMap );
+    return QVariant( modeMap.size() > 0 );
   }
   return QVariant( false );
 }
 
 //=======================================================================
 //function : isPreComputable
   }
   return QVariant( false );
 }
 
 //=======================================================================
 //function : isPreComputable
-//purpose  : 
+//purpose  : returns true for a mesh with algorithms
 //=======================================================================
 
 QVariant SMESHGUI_Selection::isPreComputable( int ind ) const
 {
 //=======================================================================
 
 QVariant SMESHGUI_Selection::isPreComputable( int ind ) const
 {
-  if ( ind >= 0 && ind < myTypes.count() && myTypes[ind] != "Unknown" )
+  if ( ind >= 0 && ind < myTypes.count() && myTypes[ind] == "Mesh" )
   {
   {
-    QMap<int,int> modeMap;
-    _PTR(SObject) pMesh = SMESH::GetActiveStudyDocument()->FindObjectID( entry( ind ).toLatin1().data() );
-    SMESHGUI_PrecomputeOp::getAssignedAlgos( pMesh, modeMap );
-    return QVariant( modeMap.size() > 1 );
+    int maxDim = dim( ind );
+    if ( maxDim < 2 ) // we can preview 1D or 2D
+    {
+      QMap<int,int> modeMap;
+      _PTR(SObject) pMesh = SMESH::GetActiveStudyDocument()->FindObjectID( entry( ind ).toLatin1().data() );
+      SMESHGUI_PrecomputeOp::getAssignedAlgos( pMesh, modeMap );
+      if ( modeMap.size() > 1 )
+        return QVariant( ( modeMap.contains( SMESH::DIM_3D )) ||
+                         ( modeMap.contains( SMESH::DIM_2D ) && maxDim < 1 ));
+    }
   }
   return QVariant( false );
 }
 
 //=======================================================================
   }
   return QVariant( false );
 }
 
 //=======================================================================
-//function : hasReference
-//purpose  : 
+//function : hasGeomReference
+//purpose  : returns true for a mesh or sub-mesh on geometry
 //=======================================================================
 
 //=======================================================================
 
-QVariant SMESHGUI_Selection::hasReference( int ind ) const
+QVariant SMESHGUI_Selection::hasGeomReference( int ind ) const
 {
 {
-  return QVariant( isReference( ind ) );
+  if ( ind >= 0 && ind < myTypes.count() && myTypes[ind] != "Unknown" )
+  {
+    _PTR(SObject) so = SMESH::GetActiveStudyDocument()->FindObjectID( entry( ind ).toLatin1().data() );
+    GEOM::GEOM_Object_var shape = SMESH::GetShapeOnMeshOrSubMesh( so );
+    return QVariant( !shape->_is_nil() );
+  }
+  return QVariant( false );
 }
 
 //=======================================================================
 }
 
 //=======================================================================
index f26b9979ce4f9f0d23c395e6e545262bd0933743..de0d0d12f1f73c02a8bc64e2623b77152d49c87a 100644 (file)
@@ -58,7 +58,7 @@ public:
   virtual int             dim( int ) const;
   virtual QVariant        isComputable( int ) const;
   virtual QVariant        isPreComputable( int ) const;
   virtual int             dim( int ) const;
   virtual QVariant        isComputable( int ) const;
   virtual QVariant        isPreComputable( int ) const;
-  virtual QVariant        hasReference( int ) const;
+  virtual QVariant        hasGeomReference( int ) const;
   virtual QVariant        isVisible( int ) const;
 
   virtual QString         quadratic2DMode( int ) const;
   virtual QVariant        isVisible( int ) const;
 
   virtual QString         quadratic2DMode( int ) const;
index 49a36cd9cad43adfe90852123f6cbb588adb7058..1d1a5300823371f4eab4faef7ead9b3da8e7374e 100644 (file)
@@ -96,6 +96,9 @@ namespace
       : _p0(p0), _p1(p1), _geomEdgeInd(iE) {}
     InSegment() : _p0(0), _p1(0), _geomEdgeInd(0) {}
 
       : _p0(p0), _p1(p1), _geomEdgeInd(iE) {}
     InSegment() : _p0(0), _p1(0), _geomEdgeInd(0) {}
 
+    const InPoint& point0() const { return *_p0; }
+    const InPoint& point1() const { return *_p1; }
+
     inline bool isConnected( const TVDEdge* edge );
 
     inline bool isExternal( const TVDEdge* edge );
     inline bool isConnected( const TVDEdge* edge );
 
     inline bool isExternal( const TVDEdge* edge );
@@ -258,8 +261,9 @@ namespace boost {
 
 namespace
 {
 
 namespace
 {
-  const int theNoBrachID = 0; // std::numeric_limits<int>::max();
-  double theScale[2]; // scale used in bndSegsToMesh()
+  const int    theNoBrachID = 0;
+  double       theScale[2]; // scale used in bndSegsToMesh()
+  const size_t theNoEdgeID = std::numeric_limits<size_t>::max() / 1000;
 
   // -------------------------------------------------------------------------------------
   /*!
 
   // -------------------------------------------------------------------------------------
   /*!
@@ -277,17 +281,18 @@ namespace
   };
   // -------------------------------------------------------------------------------------
   /*!
   };
   // -------------------------------------------------------------------------------------
   /*!
-   * \brief A segment on EDGE, used to create BndPoints
+   * \brief Segment of EDGE, used to create BndPoints
    */
   struct BndSeg
   {
     InSegment*       _inSeg;
     const TVDEdge*   _edge;
     double           _uLast;
    */
   struct BndSeg
   {
     InSegment*       _inSeg;
     const TVDEdge*   _edge;
     double           _uLast;
+    BndSeg*          _prev; // previous BndSeg in FACE boundary
     int              _branchID; // negative ID means reverse direction
 
     BndSeg( InSegment* seg, const TVDEdge* edge, double u ):
     int              _branchID; // negative ID means reverse direction
 
     BndSeg( InSegment* seg, const TVDEdge* edge, double u ):
-      _inSeg(seg), _edge(edge), _uLast(u), _branchID( theNoBrachID ) {}
+      _inSeg(seg), _edge(edge), _uLast(u), _prev(0), _branchID( theNoBrachID ) {}
 
     void setIndexToEdge( size_t id )
     {
 
     void setIndexToEdge( size_t id )
     {
@@ -298,21 +303,39 @@ namespace
 
     size_t geomEdge() const { return _inSeg->_geomEdgeInd; }
 
 
     size_t geomEdge() const { return _inSeg->_geomEdgeInd; }
 
-    void setBranch( int branchID, vector< BndSeg >& bndSegs )
+    static BndSeg* getBndSegOfEdge( const TVDEdge*              edge,
+                                    vector< vector< BndSeg > >& bndSegsPerEdge )
     {
     {
-      _branchID = branchID;
-
-      if ( _edge ) // pass branch to an opposite BndSeg
+      BndSeg* seg = 0;
+      if ( edge )
       {
       {
-        size_t oppSegIndex = SMESH_MAT2d::Branch::getBndSegment( _edge->twin() );
-        if ( oppSegIndex < bndSegs.size() && bndSegs[ oppSegIndex ]._branchID == theNoBrachID )
-          bndSegs[ oppSegIndex ]._branchID = -branchID;
+        size_t oppSegIndex  = SMESH_MAT2d::Branch::getBndSegment( edge );
+        size_t oppEdgeIndex = SMESH_MAT2d::Branch::getGeomEdge  ( edge );
+        if ( oppEdgeIndex < bndSegsPerEdge.size() &&
+             oppSegIndex < bndSegsPerEdge[ oppEdgeIndex ].size() )
+        {
+          seg = & bndSegsPerEdge[ oppEdgeIndex ][ oppSegIndex ];
+        }
       }
       }
+      return seg;
     }
     }
-    bool hasOppositeEdge( const size_t noEdgeID )
+
+    void setBranch( int branchID, vector< vector< BndSeg > >& bndSegsPerEdge )
+    {
+      _branchID = branchID;
+
+      // pass branch to an opposite BndSeg
+      if ( _edge )
+        if ( BndSeg* oppSeg = getBndSegOfEdge( _edge->twin(), bndSegsPerEdge ))
+        {
+          if ( oppSeg->_branchID == theNoBrachID )
+            oppSeg->_branchID = -branchID;
+        }
+    }
+    bool hasOppositeEdge()
     {
       if ( !_edge ) return false;
     {
       if ( !_edge ) return false;
-      return ( _inSeg->getGeomEdge( _edge->twin()->cell() ) != noEdgeID );
+      return ( _inSeg->getGeomEdge( _edge->twin()->cell() ) != theNoEdgeID );
     }
 
     // check a next segment in CW order
     }
 
     // check a next segment in CW order
@@ -352,6 +375,35 @@ namespace
 
       return false;
     }
 
       return false;
     }
+  }; // struct BndSeg
+
+  // -------------------------------------------------------------------------------------
+  /*!
+   * \brief Iterator 
+   */
+  struct BranchIterator
+  {
+    int                                 _i, _size;
+    const std::vector<const TVDEdge*> & _edges;
+    bool                                _closed;
+
+    BranchIterator(const std::vector<const TVDEdge*> & edges, int i )
+      :_i( i ), _size( edges.size() ), _edges( edges )
+    {
+      _closed = ( edges[0]->vertex1() == edges.back()->vertex0() ); // closed branch
+    }
+    const TVDEdge* operator++() { ++_i; return edge(); }
+    const TVDEdge* operator--() { --_i; return edge(); }
+    bool operator<( const BranchIterator& other ) { return _i < other._i; }
+    BranchIterator& operator=( const BranchIterator& other ) { _i = other._i; return *this; }
+    void set(int i) { _i = i; }
+    int  index() const { return _i; }
+    int  indexMod() const { return ( _i + _size ) % _size; }
+    const TVDEdge* edge() const {
+      return _closed ? _edges[ indexMod() ] : ( _i < 0 || _i >= _size ) ? 0 : _edges[ _i ];
+    }
+    const TVDEdge* edgePrev() { --_i; const TVDEdge* e = edge(); ++_i; return e; }
+    const TVDEdge* edgeNext() { ++_i; const TVDEdge* e = edge(); --_i; return e; }
   };
 
   //================================================================================
   };
 
   //================================================================================
@@ -670,22 +722,25 @@ namespace
    */
   //================================================================================
 
    */
   //================================================================================
 
-  void updateJoinedBranch( vector< const TVDEdge* > & branchEdges,
-                           const size_t               newID,
-                           vector< BndSeg > &         bndSegs,
-                           const bool                 reverse)
+  void updateJoinedBranch( vector< const TVDEdge* > &   branchEdges,
+                           const size_t                 newID,
+                           vector< vector< BndSeg > > & bndSegs,
+                           const bool                   reverse)
   {
   {
+    BndSeg *seg1, *seg2;
     if ( reverse )
     {
       for ( size_t i = 0; i < branchEdges.size(); ++i )
       {
     if ( reverse )
     {
       for ( size_t i = 0; i < branchEdges.size(); ++i )
       {
-        size_t seg1 = SMESH_MAT2d::Branch::getBndSegment( branchEdges[i] );
-        size_t seg2 = SMESH_MAT2d::Branch::getBndSegment( branchEdges[i]->twin() );
-        bndSegs[ seg1 ]._branchID /= bndSegs[ seg1 ].branchID();
-        bndSegs[ seg2 ]._branchID /= bndSegs[ seg2 ].branchID();
-        bndSegs[ seg1 ]._branchID *= -newID;
-        bndSegs[ seg2 ]._branchID *= -newID;
-        branchEdges[i] = branchEdges[i]->twin();
+        if (( seg1 = BndSeg::getBndSegOfEdge( branchEdges[i],         bndSegs )) &&
+            ( seg2 = BndSeg::getBndSegOfEdge( branchEdges[i]->twin(), bndSegs )))
+        {
+          seg1->_branchID /= seg1->branchID();
+          seg2->_branchID /= seg2->branchID();
+          seg1->_branchID *= -newID;
+          seg2->_branchID *= -newID;
+          branchEdges[i] = branchEdges[i]->twin();
+        }
       }
       std::reverse( branchEdges.begin(), branchEdges.end() );
     }
       }
       std::reverse( branchEdges.begin(), branchEdges.end() );
     }
@@ -693,12 +748,14 @@ namespace
     {
       for ( size_t i = 0; i < branchEdges.size(); ++i )
       {
     {
       for ( size_t i = 0; i < branchEdges.size(); ++i )
       {
-        size_t seg1 = SMESH_MAT2d::Branch::getBndSegment( branchEdges[i] );
-        size_t seg2 = SMESH_MAT2d::Branch::getBndSegment( branchEdges[i]->twin() );
-        bndSegs[ seg1 ]._branchID /= bndSegs[ seg1 ].branchID();
-        bndSegs[ seg2 ]._branchID /= bndSegs[ seg2 ].branchID();
-        bndSegs[ seg1 ]._branchID *= newID;
-        bndSegs[ seg2 ]._branchID *= newID;
+        if (( seg1 = BndSeg::getBndSegOfEdge( branchEdges[i],         bndSegs )) &&
+            ( seg2 = BndSeg::getBndSegOfEdge( branchEdges[i]->twin(), bndSegs )))
+        {
+          seg1->_branchID /= seg1->branchID();
+          seg2->_branchID /= seg2->branchID();
+          seg1->_branchID *= newID;
+          seg2->_branchID *= newID;
+        }
       }
     }
   }
       }
     }
   }
@@ -723,9 +780,7 @@ namespace
                vector< const SMESH_MAT2d::BranchEnd* >& branchPnt,
                SMESH_MAT2d::Boundary&                   boundary )
   {
                vector< const SMESH_MAT2d::BranchEnd* >& branchPnt,
                SMESH_MAT2d::Boundary&                   boundary )
   {
-    const size_t noEdgeID = inSegments.size() + 1; // ID of non-existent geom EDGE
-
-    // Associate MA cells with inSegments
+    // Associate MA cells with geom EDGEs
     for (TVD::const_cell_iterator it = vd.cells().begin(); it != vd.cells().end(); ++it)
     {
       const TVDCell* cell = &(*it);
     for (TVD::const_cell_iterator it = vd.cells().begin(); it != vd.cells().end(); ++it)
     {
       const TVDCell* cell = &(*it);
@@ -737,7 +792,7 @@ namespace
       }
       else
       {
       }
       else
       {
-        InSegment::setGeomEdgeToCell( cell, noEdgeID );
+        InSegment::setGeomEdgeToCell( cell, theNoEdgeID );
       }
     }
 
       }
     }
 
@@ -806,7 +861,7 @@ namespace
         {
           if ( edge->is_primary() ) break; // this should not happen
           const TVDEdge* edge2 = edge->twin(); // we are in a neighbor cell, add MA edges to inPnt
         {
           if ( edge->is_primary() ) break; // this should not happen
           const TVDEdge* edge2 = edge->twin(); // we are in a neighbor cell, add MA edges to inPnt
-          if ( inSeg.getGeomEdge( edge2->cell() ) != noEdgeID )
+          if ( inSeg.getGeomEdge( edge2->cell() ) != theNoEdgeID )
             break; // cell of an InSegment
           bool hasInfinite = false;
           list< const TVDEdge* > pointEdges;
             break; // cell of an InSegment
           bool hasInfinite = false;
           list< const TVDEdge* > pointEdges;
@@ -840,63 +895,96 @@ namespace
     if ( inPoints.front() == inPoints.back() /*&& !inPoints[0]._edges.empty()*/ )
     {
       inPntChecked[0] = false; // do not use the 1st point twice
     if ( inPoints.front() == inPoints.back() /*&& !inPoints[0]._edges.empty()*/ )
     {
       inPntChecked[0] = false; // do not use the 1st point twice
-      //InSegment::setGeomEdgeToCell( inPoints[0]._edges.back()->cell(), noEdgeID );
+      //InSegment::setGeomEdgeToCell( inPoints[0]._edges.back()->cell(), theNoEdgeID );
       inPoints[0]._edges.clear();
     }
 
     // Divide InSegment's into BndSeg's (so that each BndSeg corresponds to one MA edge)
 
       inPoints[0]._edges.clear();
     }
 
     // Divide InSegment's into BndSeg's (so that each BndSeg corresponds to one MA edge)
 
-    vector< BndSeg > bndSegs;
-    bndSegs.reserve( inSegments.size() * 3 );
-
-    list< const TVDEdge* >::reverse_iterator e;
-    for ( size_t i = 0; i < inSegments.size(); ++i )
+    vector< vector< BndSeg > > bndSegsPerEdge( boundary.nbEdges() ); // all BndSeg's
     {
     {
-      InSegment& inSeg = inSegments[i];
+      vector< BndSeg > bndSegs; // bndSeg's of a current EDGE
+      size_t prevGeomEdge = theNoEdgeID;
 
 
-      // segments around 1st concave point
-      size_t ip0 = inSeg._p0->index( inPoints );
-      if ( inPntChecked[ ip0 ] )
-        for ( e = inSeg._p0->_edges.rbegin(); e != inSeg._p0->_edges.rend(); ++e )
-          bndSegs.push_back( BndSeg( &inSeg, *e, inSeg._p0->_param ));
-      inPntChecked[ ip0 ] = false;
-
-      // segments of InSegment's
-      const size_t nbMaEdges = inSeg._edges.size();
-      switch ( nbMaEdges ) {
-      case 0: // "around" circle center
-        bndSegs.push_back( BndSeg( &inSeg, 0, inSeg._p1->_param )); break;
-      case 1:
-        bndSegs.push_back( BndSeg( &inSeg, inSeg._edges.back(), inSeg._p1->_param )); break;
-      default:
-        gp_XY inSegDir( inSeg._p1->_a - inSeg._p0->_a,
-                        inSeg._p1->_b - inSeg._p0->_b );
-        const double inSegLen2 = inSegDir.SquareModulus();
-        e = inSeg._edges.rbegin();
-        for ( size_t iE = 1; iE < nbMaEdges; ++e, ++iE )
+      list< const TVDEdge* >::reverse_iterator e;
+      for ( size_t i = 0; i < inSegments.size(); ++i )
+      {
+        InSegment& inSeg = inSegments[i];
+
+        if ( inSeg._geomEdgeInd != prevGeomEdge )
         {
         {
-          gp_XY toMA( (*e)->vertex0()->x() - inSeg._p0->_a,
-                      (*e)->vertex0()->y() - inSeg._p0->_b );
-          double r = toMA * inSegDir / inSegLen2;
-          double u = r * inSeg._p1->_param + ( 1. - r ) * inSeg._p0->_param;
-          bndSegs.push_back( BndSeg( &inSeg, *e, u ));
+          if ( !bndSegs.empty() )
+            bndSegsPerEdge[ prevGeomEdge ].swap( bndSegs );
+          prevGeomEdge = inSeg._geomEdgeInd;
         }
         }
-        bndSegs.push_back( BndSeg( &inSeg, *e, inSeg._p1->_param ));
-      }
-      // segments around 2nd concave point
-      size_t ip1 = inSeg._p1->index( inPoints );
-      if ( inPntChecked[ ip1 ] )
-        for ( e = inSeg._p1->_edges.rbegin(); e != inSeg._p1->_edges.rend(); ++e )
+
+        // segments around 1st concave point
+        size_t ip0 = inSeg._p0->index( inPoints );
+        if ( inPntChecked[ ip0 ] )
+          for ( e = inSeg._p0->_edges.rbegin(); e != inSeg._p0->_edges.rend(); ++e )
+            bndSegs.push_back( BndSeg( &inSeg, *e, inSeg._p0->_param ));
+        inPntChecked[ ip0 ] = false;
+
+        // segments of InSegment's
+        const size_t nbMaEdges = inSeg._edges.size();
+        switch ( nbMaEdges ) {
+        case 0: // "around" circle center
+          bndSegs.push_back( BndSeg( &inSeg, 0, inSeg._p1->_param )); break;
+        case 1:
+          bndSegs.push_back( BndSeg( &inSeg, inSeg._edges.back(), inSeg._p1->_param )); break;
+        default:
+          gp_XY inSegDir( inSeg._p1->_a - inSeg._p0->_a,
+                          inSeg._p1->_b - inSeg._p0->_b );
+          const double inSegLen2 = inSegDir.SquareModulus();
+          e = inSeg._edges.rbegin();
+          for ( size_t iE = 1; iE < nbMaEdges; ++e, ++iE )
+          {
+            gp_XY toMA( (*e)->vertex0()->x() - inSeg._p0->_a,
+                        (*e)->vertex0()->y() - inSeg._p0->_b );
+            double r = toMA * inSegDir / inSegLen2;
+            double u = r * inSeg._p1->_param + ( 1. - r ) * inSeg._p0->_param;
+            bndSegs.push_back( BndSeg( &inSeg, *e, u ));
+          }
           bndSegs.push_back( BndSeg( &inSeg, *e, inSeg._p1->_param ));
           bndSegs.push_back( BndSeg( &inSeg, *e, inSeg._p1->_param ));
-      inPntChecked[ ip1 ] = false;
+        }
+        // segments around 2nd concave point
+        size_t ip1 = inSeg._p1->index( inPoints );
+        if ( inPntChecked[ ip1 ] )
+          for ( e = inSeg._p1->_edges.rbegin(); e != inSeg._p1->_edges.rend(); ++e )
+            bndSegs.push_back( BndSeg( &inSeg, *e, inSeg._p1->_param ));
+        inPntChecked[ ip1 ] = false;
+      }
+      if ( !bndSegs.empty() )
+        bndSegsPerEdge[ prevGeomEdge ].swap( bndSegs );
     }
 
     }
 
-    // make TVDEdge's know it's BndSeg to enable passing branchID to
-    // an opposite BndSeg in BndSeg::setBranch()
-    for ( size_t i = 0; i < bndSegs.size(); ++i )
-      bndSegs[i].setIndexToEdge( i );
+    // prepare to MA branch search
+    for ( size_t iE = 0; iE < bndSegsPerEdge.size(); ++iE )
+    {
+      // 1) make TVDEdge's know it's BndSeg to enable passing branchID to
+      // an opposite BndSeg in BndSeg::setBranch(); geom EDGE ID is known from TVDCell
+      // 2) connect bndSegs via BndSeg::_prev
+
+      vector< BndSeg >& bndSegs = bndSegsPerEdge[ iE ];
+      if ( bndSegs.empty() ) continue;
+
+      for ( size_t i = 1; i < bndSegs.size(); ++i )
+      {
+        bndSegs[i]._prev = & bndSegs[i-1];
+        bndSegs[i].setIndexToEdge( i );
+      }
+      // look for the last bndSeg of previous EDGE to set bndSegs[0]._prev
+      const InPoint& p0 = bndSegs[0]._inSeg->point0();
+      for ( size_t iE2 = 0; iE2 < bndSegsPerEdge.size(); ++iE2 )
+        if ( p0 == bndSegsPerEdge[ iE2 ].back()._inSeg->point1() )
+        {
+          bndSegs[0]._prev = & bndSegsPerEdge[ iE2 ].back();
+          break;
+        }
+      bndSegs[0].setIndexToEdge( 0 );
+    }
 
 
-    bndSegsToMesh( bndSegs ); // debug: visually check found MA edges
+    //bndSegsToMesh( bndSegsPerEdge ); // debug: visually check found MA edges
 
 
     // Find TVDEdge's of Branches and associate them with bndSegs
 
 
     // Find TVDEdge's of Branches and associate them with bndSegs
@@ -907,71 +995,67 @@ namespace
     map< const TVDVertex*, SMESH_MAT2d::BranchEndType > endType;
 
     int branchID = 1; // we code orientation as branchID sign
     map< const TVDVertex*, SMESH_MAT2d::BranchEndType > endType;
 
     int branchID = 1; // we code orientation as branchID sign
-    branchEdges.resize( branchID + 1 );
-
-    size_t i1st = 0;
-    while ( i1st < bndSegs.size() && !bndSegs[i1st].hasOppositeEdge( noEdgeID ))
-      ++i1st;
-    bndSegs[i1st].setBranch( branchID, bndSegs ); // set to the i-th and to the opposite bndSeg
-    branchEdges[ branchID ].push_back( bndSegs[i1st]._edge );
+    branchEdges.resize( branchID );
 
 
-    for ( size_t i = i1st+1; i < bndSegs.size(); ++i )
+    for ( size_t iE = 0; iE < bndSegsPerEdge.size(); ++iE )
     {
     {
-      if ( bndSegs[i].branchID() )
+      vector< BndSeg >& bndSegs = bndSegsPerEdge[ iE ];
+      for ( size_t i = 0; i < bndSegs.size(); ++i )
       {
       {
-        branchID = bndSegs[i]._branchID; // with sign
+        if ( bndSegs[i].branchID() )
+        {
+          if ( bndSegs[i]._prev &&
+               bndSegs[i]._branchID == -bndSegs[i]._prev->_branchID &&
+               bndSegs[i]._edge )
+          {
+            SMESH_MAT2d::BranchEndType type =
+              ( bndSegs[i]._inSeg->isConnected( bndSegs[i]._edge ) ?
+                SMESH_MAT2d::BE_ON_VERTEX :
+                SMESH_MAT2d::BE_END );
+            endType.insert( make_pair( bndSegs[i]._edge->vertex1(), type ));
+          }
+          continue;
+        }
+        if ( !bndSegs[i]._prev &&
+             !bndSegs[i].hasOppositeEdge() )
+          continue;
 
 
-        if ( bndSegs[i]._branchID == -bndSegs[i-1]._branchID &&
-             bndSegs[i]._edge )
+        if ( !bndSegs[i]._prev ||
+             !bndSegs[i]._prev->isSameBranch( bndSegs[i] ))
         {
         {
-          SMESH_MAT2d::BranchEndType type =
-            ( bndSegs[i]._inSeg->isConnected( bndSegs[i]._edge ) ?
-              SMESH_MAT2d::BE_ON_VERTEX :
-              SMESH_MAT2d::BE_END );
-          endType.insert( make_pair( bndSegs[i]._edge->vertex1(), type ));
+          branchEdges.resize(( branchID = branchEdges.size()) + 1 );
+          if ( bndSegs[i]._edge && bndSegs[i]._prev )
+            endType.insert( make_pair( bndSegs[i]._edge->vertex1(), SMESH_MAT2d::BE_BRANCH_POINT ));
         }
         }
-        continue;
-      }
-      if ( !bndSegs[i-1].isSameBranch( bndSegs[i] ))
-      {
-        branchEdges.resize(( branchID = branchEdges.size()) + 1 );
-        if ( bndSegs[i]._edge )
-          endType.insert( make_pair( bndSegs[i]._edge->vertex1(),
-                                     SMESH_MAT2d::BE_BRANCH_POINT ));
-      }
-      bndSegs[i].setBranch( branchID, bndSegs ); // set to i-th and to the opposite bndSeg
-      if ( bndSegs[i].hasOppositeEdge( noEdgeID ))
-        branchEdges[ bndSegs[i].branchID() ].push_back( bndSegs[i]._edge );
-    }
-    // define BranchEndType of the first TVDVertex
-    if ( bndSegs.front()._branchID == -bndSegs.back()._branchID )
-    {
-      if ( bndSegs[0]._edge )
-      {
-        SMESH_MAT2d::BranchEndType type =
-          ( bndSegs[0]._inSeg->isConnected( bndSegs[0]._edge ) ?
-            SMESH_MAT2d::BE_ON_VERTEX :
-            SMESH_MAT2d::BE_END );
-        endType.insert( make_pair( bndSegs[0]._edge->vertex1(), type ));
-      }
-      else if ( bndSegs.back()._edge )
-      {
-        SMESH_MAT2d::BranchEndType type =
-          ( bndSegs.back()._inSeg->isConnected( bndSegs.back()._edge ) ?
-            SMESH_MAT2d::BE_ON_VERTEX :
-            SMESH_MAT2d::BE_END );
-        endType.insert( make_pair( bndSegs.back()._edge->vertex0(), type ));
+        else if ( bndSegs[i]._prev->_branchID )
+        {
+          branchID = bndSegs[i]._prev->_branchID;  // with sign
+        }
+        else if ( bndSegs[i]._edge && // 1st bndSeg of a WIRE
+                  bndSegs[i]._inSeg->isConnected( bndSegs[i]._edge ))
+        {
+          branchEdges.resize(( branchID = branchEdges.size()) + 1 );
+          if ( bndSegs[i]._inSeg->point0() == bndSegs[i]._edge->vertex1() )
+            endType.insert( make_pair( bndSegs[i]._edge->vertex1(), SMESH_MAT2d::BE_ON_VERTEX ));
+          else
+            endType.insert( make_pair( bndSegs[i]._edge->vertex0(), SMESH_MAT2d::BE_ON_VERTEX ));
+        }
+
+        bndSegs[i].setBranch( branchID, bndSegsPerEdge ); // set to i-th and to the opposite bndSeg
+        if ( bndSegs[i].hasOppositeEdge() )
+          branchEdges[ bndSegs[i].branchID() ].push_back( bndSegs[i]._edge );
       }
     }
       }
     }
+
     // join the 1st and the last branch edges if it is the same branch
     // join the 1st and the last branch edges if it is the same branch
-    if ( bndSegs.back().branchID() != bndSegs.front().branchID() &&
-         bndSegs.back().isSameBranch( bndSegs.front() ))
-    {
-      vector<const TVDEdge*> & br1 = branchEdges[ bndSegs.front().branchID() ];
-      vector<const TVDEdge*> & br2 = branchEdges[ bndSegs.back().branchID()  ];
-      br1.insert( br1.begin(), br2.begin(), br2.end() );
-      br2.clear();
-    }
+    // if ( bndSegs.back().branchID() != bndSegs.front().branchID() &&
+    //      bndSegs.back().isSameBranch( bndSegs.front() ))
+    // {
+    //   vector<const TVDEdge*> & br1 = branchEdges[ bndSegs.front().branchID() ];
+    //   vector<const TVDEdge*> & br2 = branchEdges[ bndSegs.back().branchID()  ];
+    //   br1.insert( br1.begin(), br2.begin(), br2.end() );
+    //   br2.clear();
+    // }
 
     // remove branches ending at BE_ON_VERTEX
 
 
     // remove branches ending at BE_ON_VERTEX
 
@@ -1010,34 +1094,38 @@ namespace
         if ( !v0 && !v1 )
           continue;
 
         if ( !v0 && !v1 )
           continue;
 
-        size_t iBrToJoin = 0;
-        for ( size_t iB2 = 1; iB2 < branchEdges.size(); ++iB2 )
+        for ( int isV0 = 0; isV0 < 2; ++isV0 )
         {
         {
-          if ( branchEdges[iB2].empty() || isBranchRemoved[iB2] || iB == iB2 )
-            continue;
-          const TVDVertex* v02 = branchEdges[iB2][0]->vertex1();
-          const TVDVertex* v12 = branchEdges[iB2].back()->vertex0();
-          if ( v0 == v02 || v0 == v12 || v1 == v02 || v1 == v12 )
+          const TVDVertex* v = isV0 ? v0 : v1;
+          size_t iBrToJoin = 0;
+          for ( size_t iB2 = 1; iB2 < branchEdges.size(); ++iB2 )
           {
           {
-            if ( iBrToJoin > 0 )
+            if ( branchEdges[iB2].empty() || isBranchRemoved[iB2] || iB == iB2 )
+              continue;
+            const TVDVertex* v02 = branchEdges[iB2][0]->vertex1();
+            const TVDVertex* v12 = branchEdges[iB2].back()->vertex0();
+            if ( v == v02 || v == v12 )
             {
             {
-              iBrToJoin = 0;
-              break; // more than 2 not removed branches meat at a TVDVertex
+              if ( iBrToJoin > 0 )
+              {
+                iBrToJoin = 0;
+                break; // more than 2 not removed branches meat at a TVDVertex
+              }
+              iBrToJoin = iB2;
             }
             }
-            iBrToJoin = iB2;
           }
           }
-        }
-        if ( iBrToJoin > 0 )
-        {
-          vector<const TVDEdge*>& branch = branchEdges[ iBrToJoin ];
-          const TVDVertex* v02 = branch[0]->vertex1();
-          const TVDVertex* v12 = branch.back()->vertex0();
-          updateJoinedBranch( branch, iB, bndSegs, /*reverse=*/(v0 == v02 || v1 == v12 ));
-          if ( v0 == v02 || v0 == v12 )
-            branchEdges[iB].insert( branchEdges[iB].begin(), branch.begin(), branch.end() );
-          else
-            branchEdges[iB].insert( branchEdges[iB].end(),   branch.begin(), branch.end() );
-          branch.clear();
+          if ( iBrToJoin > 0 )
+          {
+            vector<const TVDEdge*>& branch = branchEdges[ iBrToJoin ];
+            const TVDVertex* v02 = branch[0]->vertex1();
+            const TVDVertex* v12 = branch.back()->vertex0();
+            updateJoinedBranch( branch, iB, bndSegsPerEdge, /*reverse=*/(v0 == v02 || v1 == v12 ));
+            if ( v0 == v02 || v0 == v12 )
+              branchEdges[iB].insert( branchEdges[iB].begin(), branch.begin(), branch.end() );
+            else
+              branchEdges[iB].insert( branchEdges[iB].end(),   branch.begin(), branch.end() );
+            branch.clear();
+          }
         }
       } // loop on branchEdges
     } // if ( ignoreCorners )
         }
       } // loop on branchEdges
     } // if ( ignoreCorners )
@@ -1064,36 +1152,31 @@ namespace
 
     // Fill in BndPoints of each EDGE of the boundary
 
 
     // Fill in BndPoints of each EDGE of the boundary
 
-    size_t iSeg = 0;
+    //size_t iSeg = 0;
     int edgeInd = -1, dInd = 0;
     int edgeInd = -1, dInd = 0;
-    while ( iSeg < bndSegs.size() )
+    for ( size_t iE = 0; iE < bndSegsPerEdge.size(); ++iE )
     {
     {
-      const size_t                geomID = bndSegs[ iSeg ].geomEdge();
-      SMESH_MAT2d::BndPoints & bndPoints = boundary.getPoints( geomID );
-
-      size_t nbSegs = 0;
-      for ( size_t i = iSeg; i < bndSegs.size() && geomID == bndSegs[ i ].geomEdge(); ++i )
-        ++nbSegs;
-      size_t iSegEnd = iSeg + nbSegs;
+      vector< BndSeg >&          bndSegs = bndSegsPerEdge[ iE ];
+      SMESH_MAT2d::BndPoints & bndPoints = boundary.getPoints( iE );
 
       // make TVDEdge know an index of bndSegs within BndPoints
 
       // make TVDEdge know an index of bndSegs within BndPoints
-      for ( size_t i = iSeg; i < iSegEnd; ++i )
+      for ( size_t i = 0; i < bndSegs.size(); ++i )
         if ( bndSegs[i]._edge )
         if ( bndSegs[i]._edge )
-          SMESH_MAT2d::Branch::setBndSegment( i - iSeg, bndSegs[i]._edge );
+          SMESH_MAT2d::Branch::setBndSegment( i, bndSegs[i]._edge );
 
       // parameters on EDGE
 
 
       // parameters on EDGE
 
-      bndPoints._params.reserve( nbSegs + 1 );
-      bndPoints._params.push_back( bndSegs[ iSeg ]._inSeg->_p0->_param );
+      bndPoints._params.reserve( bndSegs.size() + 1 );
+      bndPoints._params.push_back( bndSegs[ 0 ]._inSeg->_p0->_param );
 
 
-      for ( size_t i = iSeg; i < iSegEnd; ++i )
+      for ( size_t i = 0; i < bndSegs.size(); ++i )
         bndPoints._params.push_back( bndSegs[ i ]._uLast );
 
       // MA edges
 
         bndPoints._params.push_back( bndSegs[ i ]._uLast );
 
       // MA edges
 
-      bndPoints._maEdges.reserve( nbSegs );
+      bndPoints._maEdges.reserve( bndSegs.size() );
 
 
-      for ( size_t i = iSeg; i < iSegEnd; ++i )
+      for ( size_t i = 0; i < bndSegs.size(); ++i )
       {
         const size_t              brID = bndSegs[ i ].branchID();
         const SMESH_MAT2d::Branch*  br = branchByID[ brID ];
       {
         const size_t              brID = bndSegs[ i ].branchID();
         const SMESH_MAT2d::Branch*  br = branchByID[ brID ];
@@ -1136,9 +1219,6 @@ namespace
         bndPoints._maEdges.push_back( make_pair( br, ( 1 + edgeInd ) * dInd ));
 
       } // loop on bndSegs of an EDGE
         bndPoints._maEdges.push_back( make_pair( br, ( 1 + edgeInd ) * dInd ));
 
       } // loop on bndSegs of an EDGE
-
-      iSeg = iSegEnd;
-
     } // loop on all bndSegs to construct Boundary
 
     // Initialize branches
     } // loop on all bndSegs to construct Boundary
 
     // Initialize branches
@@ -1352,7 +1432,7 @@ bool SMESH_MAT2d::Boundary::moveToClosestEdgeEnd( BoundaryPoint& bp ) const
     return false;
 
   const BndPoints& points = _pointsPerEdge[ bp._edgeIndex ];
     return false;
 
   const BndPoints& points = _pointsPerEdge[ bp._edgeIndex ];
-  if ( bp._param - points._params[0] < points._params.back() - bp._param )
+  if ( Abs( bp._param - points._params[0]) < Abs( points._params.back() - bp._param ))
     bp._param = points._params[0];
   else 
     bp._param = points._params.back();
     bp._param = points._params[0];
   else 
     bp._param = points._params.back();
@@ -1658,7 +1738,7 @@ bool SMESH_MAT2d::Branch::addDivPntForConcaVertex( std::vector< std::size_t >&
                                                    std::vector< BranchPoint >&   divPoints,
                                                    const vector<const TVDEdge*>& maEdges,
                                                    const vector<const TVDEdge*>& maEdgesTwin,
                                                    std::vector< BranchPoint >&   divPoints,
                                                    const vector<const TVDEdge*>& maEdges,
                                                    const vector<const TVDEdge*>& maEdgesTwin,
-                                                   size_t &                    i) const
+                                                   int &                         i) const
 {
   // if there is a concave vertex between EDGEs
   // then position of a dividing BranchPoint is undefined, it is somewhere
 {
   // if there is a concave vertex between EDGEs
   // then position of a dividing BranchPoint is undefined, it is somewhere
@@ -1670,11 +1750,13 @@ bool SMESH_MAT2d::Branch::addDivPntForConcaVertex( std::vector< std::size_t >&
   BranchPoint divisionPnt;
   divisionPnt._branch = this;
 
   BranchPoint divisionPnt;
   divisionPnt._branch = this;
 
+  BranchIterator iCur( maEdges, i );
+
   size_t ie1 = getGeomEdge( maEdges    [i] );
   size_t ie2 = getGeomEdge( maEdgesTwin[i] );
 
   size_t ie1 = getGeomEdge( maEdges    [i] );
   size_t ie2 = getGeomEdge( maEdgesTwin[i] );
 
-  size_t iSeg1  = getBndSegment( maEdges[ i-1 ] );
-  size_t iSeg2  = getBndSegment( maEdges[ i ] );
+  size_t iSeg1  = getBndSegment( iCur.edgePrev() );
+  size_t iSeg2  = getBndSegment( iCur.edge() );
   bool isConcaPrev = _boundary->isConcaveSegment( edgeIDs1.back(), iSeg1 );
   bool isConcaNext = _boundary->isConcaveSegment( ie1,             iSeg2 );
   if ( !isConcaNext && !isConcaPrev )
   bool isConcaPrev = _boundary->isConcaveSegment( edgeIDs1.back(), iSeg1 );
   bool isConcaNext = _boundary->isConcaveSegment( ie1,             iSeg2 );
   if ( !isConcaNext && !isConcaPrev )
@@ -1682,46 +1764,48 @@ bool SMESH_MAT2d::Branch::addDivPntForConcaVertex( std::vector< std::size_t >&
 
   bool isConcaveV = false;
 
 
   bool isConcaveV = false;
 
-  int iPrev = i-1, iNext = i;
+  const TVDEdge* maE;
+  BranchIterator iPrev( maEdges, i ), iNext( maEdges, i );
+   --iPrev;
   if ( isConcaNext ) // all null-length segments follow
   {
     // look for a VERTEX of the opposite EDGE
   if ( isConcaNext ) // all null-length segments follow
   {
     // look for a VERTEX of the opposite EDGE
-    ++iNext; // end of null-length segments
-    while ( iNext < maEdges.size() )
+    // iNext - next after all null-length segments
+    while ( maE = ++iNext )
     {
     {
-      iSeg2 = getBndSegment( maEdges[ iNext ] );
-      if ( _boundary->isConcaveSegment( ie1, iSeg2 ))
-        ++iNext;
-      else
+      iSeg2 = getBndSegment( maE );
+      if ( !_boundary->isConcaveSegment( ie1, iSeg2 ))
         break;
     }
     bool vertexFound = false;
         break;
     }
     bool vertexFound = false;
-    for ( size_t iE = i+1; iE < iNext; ++iE )
+    for ( ++iCur; iCur < iNext; ++iCur )
     {
     {
-      ie2 = getGeomEdge( maEdgesTwin[iE] );
+      ie2 = getGeomEdge( maEdgesTwin[ iCur.indexMod() ] );
       if ( ie2 != edgeIDs2.back() )
       {
         // opposite VERTEX found
       if ( ie2 != edgeIDs2.back() )
       {
         // opposite VERTEX found
-        divisionPnt._iEdge = iE;
+        divisionPnt._iEdge = iCur.indexMod();
         divisionPnt._edgeParam = 0;
         divPoints.push_back( divisionPnt );
         edgeIDs1.push_back( ie1 );
         edgeIDs2.push_back( ie2 );
         vertexFound = true;
         divisionPnt._edgeParam = 0;
         divPoints.push_back( divisionPnt );
         edgeIDs1.push_back( ie1 );
         edgeIDs2.push_back( ie2 );
         vertexFound = true;
-        }
+      }
     }
     if ( vertexFound )
     {
     }
     if ( vertexFound )
     {
-      iPrev = i = --iNext; // not to add a BP in the moddle
+      --iNext;
+      iPrev = iNext; // not to add a BP in the moddle
+      i = iNext.indexMod();
       isConcaveV = true;
     }
   }
   else if ( isConcaPrev )
   {
     // all null-length segments passed, find their beginning
       isConcaveV = true;
     }
   }
   else if ( isConcaPrev )
   {
     // all null-length segments passed, find their beginning
-    while ( iPrev-1 >= 0 )
+    while ( maE = iPrev.edgePrev() )
     {
     {
-      iSeg1 = getBndSegment( maEdges[ iPrev-1 ] );
+      iSeg1 = getBndSegment( maE );
       if ( _boundary->isConcaveSegment( edgeIDs1.back(), iSeg1 ))
         --iPrev;
       else
       if ( _boundary->isConcaveSegment( edgeIDs1.back(), iSeg1 ))
         --iPrev;
       else
@@ -1729,17 +1813,18 @@ bool SMESH_MAT2d::Branch::addDivPntForConcaVertex( std::vector< std::size_t >&
     }
   }
 
     }
   }
 
-  if ( iPrev < i-1 || iNext > i )
+  if ( iPrev.index() < i-1 || iNext.index() > i )
   {
     // no VERTEX on the opposite EDGE, put the Branch Point in the middle
   {
     // no VERTEX on the opposite EDGE, put the Branch Point in the middle
-    double par1 = _params[ iPrev+1 ], par2 = _params[ iNext ];
+    divisionPnt._iEdge = iPrev.indexMod();
+    ++iPrev;
+    double   par1 = _params[ iPrev.indexMod() ], par2 = _params[ iNext.indexMod() ];
     double midPar = 0.5 * ( par1 + par2 );
     double midPar = 0.5 * ( par1 + par2 );
-    divisionPnt._iEdge = iPrev;
-    while ( _params[ divisionPnt._iEdge + 1 ] < midPar )
-      ++divisionPnt._iEdge;
+    for ( ; _params[ iPrev.indexMod() ] < midPar; ++iPrev )
+      divisionPnt._iEdge = iPrev.indexMod();
     divisionPnt._edgeParam =
     divisionPnt._edgeParam =
-      ( _params[ divisionPnt._iEdge + 1 ] - midPar ) /
-      ( _params[ divisionPnt._iEdge + 1 ] - _params[ divisionPnt._iEdge ] );
+      ( _params[ iPrev.indexMod() ] - midPar ) /
+      ( _params[ iPrev.indexMod() ] - _params[ divisionPnt._iEdge ] );
     divPoints.push_back( divisionPnt );
     isConcaveV = true;
   }
     divPoints.push_back( divisionPnt );
     isConcaveV = true;
   }
@@ -1767,50 +1852,74 @@ void SMESH_MAT2d::Branch::getOppositeGeomEdges( std::vector< std::size_t >& edge
   edgeIDs2.clear();
   divPoints.clear();
 
   edgeIDs2.clear();
   divPoints.clear();
 
-  edgeIDs1.push_back( getGeomEdge( _maEdges[0] ));
-  edgeIDs2.push_back( getGeomEdge( _maEdges[0]->twin() ));
-
   std::vector<const TVDEdge*> twins( _maEdges.size() );
   for ( size_t i = 0; i < _maEdges.size(); ++i )
     twins[i] = _maEdges[i]->twin();
 
   std::vector<const TVDEdge*> twins( _maEdges.size() );
   for ( size_t i = 0; i < _maEdges.size(); ++i )
     twins[i] = _maEdges[i]->twin();
 
+  BranchIterator maIter ( _maEdges, 0 );
+  BranchIterator twIter ( twins, 0 );
   // size_t lastConcaE1 = _boundary.nbEdges();
   // size_t lastConcaE2 = _boundary.nbEdges();
 
   // size_t lastConcaE1 = _boundary.nbEdges();
   // size_t lastConcaE2 = _boundary.nbEdges();
 
+  // if ( maIter._closed ) // closed branch
+  // {
+  //   edgeIDs1.push_back( getGeomEdge( _maEdges.back() ));
+  //   edgeIDs2.push_back( getGeomEdge( _maEdges.back()->twin() ));
+  // }
+  // else
+  {
+    edgeIDs1.push_back( getGeomEdge( maIter.edge() ));
+    edgeIDs2.push_back( getGeomEdge( twIter.edge() ));
+  }
+
   BranchPoint divisionPnt;
   divisionPnt._branch = this;
 
   BranchPoint divisionPnt;
   divisionPnt._branch = this;
 
-  for ( size_t i = 0; i < _maEdges.size(); ++i )
+  for ( ++maIter, ++twIter; maIter.index() < _maEdges.size(); ++maIter, ++twIter )
   {
   {
-    size_t ie1 = getGeomEdge( _maEdges[i] );
-    size_t ie2 = getGeomEdge( _maEdges[i]->twin() );
-    
-    if ( edgeIDs1.back() != ie1 || edgeIDs2.back() != ie2 )
+    size_t ie1 = getGeomEdge( maIter.edge() );
+    size_t ie2 = getGeomEdge( twIter.edge() );
+
+    bool otherE1 = ( edgeIDs1.back() != ie1 );
+    bool otherE2 = ( edgeIDs2.back() != ie2 );
+
+    if ( !otherE1 && !otherE2 && maIter._closed )
+    {
+      int iSegPrev1 = getBndSegment( maIter.edgePrev() );
+      int iSegCur1  = getBndSegment( maIter.edge() );
+      otherE1 = Abs( iSegPrev1 - iSegCur1 ) != 1;
+      int iSegPrev2 = getBndSegment( twIter.edgePrev() );
+      int iSegCur2  = getBndSegment( twIter.edge() );
+      otherE2 = Abs( iSegPrev2 - iSegCur2 ) != 1;
+    }
+
+    if ( otherE1 || otherE2 )
     {
       bool isConcaveV = false;
     {
       bool isConcaveV = false;
-      if ( edgeIDs1.back() != ie1 && edgeIDs2.back() == ie2 )
+      if ( otherE1 && !otherE2 )
       {
       {
-        isConcaveV = addDivPntForConcaVertex( edgeIDs1, edgeIDs2, divPoints, _maEdges, twins, i );
+        isConcaveV = addDivPntForConcaVertex( edgeIDs1, edgeIDs2, divPoints,
+                                              _maEdges, twins, maIter._i );
       }
       }
-      if ( edgeIDs1.back() == ie1 && edgeIDs2.back() != ie2 )
+      if ( !otherE1 && otherE2 )
       {
       {
-        isConcaveV = addDivPntForConcaVertex( edgeIDs2, edgeIDs1, divPoints, twins, _maEdges, i );
+        isConcaveV = addDivPntForConcaVertex( edgeIDs2, edgeIDs1, divPoints,
+                                              twins, _maEdges, maIter._i );
       }
 
       if ( isConcaveV )
       {
       }
 
       if ( isConcaveV )
       {
-        ie1 = getGeomEdge( _maEdges[i] );
-        ie2 = getGeomEdge( _maEdges[i]->twin() );
+        ie1 = getGeomEdge( maIter.edge() );
+        ie2 = getGeomEdge( twIter.edge() );
       }
       }
-      if (( !isConcaveV ) ||
-          ( edgeIDs1.back() != ie1 || edgeIDs2.back() != ie2 ))
+      if ( !isConcaveV || otherE1 || otherE2 )
       {
         edgeIDs1.push_back( ie1 );
         edgeIDs2.push_back( ie2 );
       }
       if ( divPoints.size() < edgeIDs1.size() - 1 )
       {
       {
         edgeIDs1.push_back( ie1 );
         edgeIDs2.push_back( ie2 );
       }
       if ( divPoints.size() < edgeIDs1.size() - 1 )
       {
-        divisionPnt._iEdge = i;
+        divisionPnt._iEdge = maIter.index();
         divisionPnt._edgeParam = 0;
         divPoints.push_back( divisionPnt );
       }
         divisionPnt._edgeParam = 0;
         divPoints.push_back( divisionPnt );
       }
index 2ba0066c5efa9566c3a5bc82427de6be63c32df5..eff5c10d5e7ef733116483d36b9f1f302b701a29 100644 (file)
@@ -138,7 +138,7 @@ namespace SMESH_MAT2d
                                   std::vector< BranchPoint >&        divPoints,
                                   const std::vector<const TVDEdge*>& maEdges,
                                   const std::vector<const TVDEdge*>& maEdgesTwin,
                                   std::vector< BranchPoint >&        divPoints,
                                   const std::vector<const TVDEdge*>& maEdges,
                                   const std::vector<const TVDEdge*>& maEdgesTwin,
-                                  size_t &                           i) const;
+                                  int &                              i) const;
 
     // association of _maEdges with boundary segments is stored in this way:
     // index of an EDGE:           TVDEdge->cell()->color()
 
     // association of _maEdges with boundary segments is stored in this way:
     // index of an EDGE:           TVDEdge->cell()->color()
index 94c76ec3d551093afaeea6ab2f01da4a1cec27e5..7ceeb904fac40eabe1104e54b046fe5bbadb9a00 100644 (file)
@@ -510,7 +510,6 @@ FunctorType Length2D_i::GetFunctorType()
 
 SMESH::Length2D::Values* Length2D_i::GetValues()
 {
 
 SMESH::Length2D::Values* Length2D_i::GetValues()
 {
-  INFOS("Length2D_i::GetValues");
   SMESH::Controls::Length2D::TValues aValues;
   (dynamic_cast<SMESH::Controls::Length2D*>(myFunctorPtr.get()))->GetValues( aValues );
 
   SMESH::Controls::Length2D::TValues aValues;
   (dynamic_cast<SMESH::Controls::Length2D*>(myFunctorPtr.get()))->GetValues( aValues );
 
@@ -530,7 +529,6 @@ SMESH::Length2D::Values* Length2D_i::GetValues()
     aValue.myPnt2 = aVal.myPntId[ 1 ];
   }
 
     aValue.myPnt2 = aVal.myPntId[ 1 ];
   }
 
-  INFOS("Length2D_i::GetValuess~");
   return aResult._retn();
 }
 
   return aResult._retn();
 }
 
@@ -581,7 +579,6 @@ FunctorType MultiConnection2D_i::GetFunctorType()
 
 SMESH::MultiConnection2D::Values* MultiConnection2D_i::GetValues()
 {
 
 SMESH::MultiConnection2D::Values* MultiConnection2D_i::GetValues()
 {
-  INFOS("MultiConnection2D_i::GetValues");
   SMESH::Controls::MultiConnection2D::MValues aValues;
   (dynamic_cast<SMESH::Controls::MultiConnection2D*>(myFunctorPtr.get()))->GetValues( aValues );
   
   SMESH::Controls::MultiConnection2D::MValues aValues;
   (dynamic_cast<SMESH::Controls::MultiConnection2D*>(myFunctorPtr.get()))->GetValues( aValues );
   
@@ -601,7 +598,6 @@ SMESH::MultiConnection2D::Values* MultiConnection2D_i::GetValues()
     aValue.myNbConnects = (*anIter).second;
   }
 
     aValue.myNbConnects = (*anIter).second;
   }
 
-  INFOS("Multiconnection2D_i::GetValuess~");
   return aResult._retn();
 }
 
   return aResult._retn();
 }
 
@@ -1218,7 +1214,6 @@ FreeEdges_i::FreeEdges_i()
 
 SMESH::FreeEdges::Borders* FreeEdges_i::GetBorders()
 {
 
 SMESH::FreeEdges::Borders* FreeEdges_i::GetBorders()
 {
-  INFOS("FreeEdges_i::GetBorders");
   SMESH::Controls::FreeEdges::TBorders aBorders;
   myFreeEdgesPtr->GetBoreders( aBorders );
 
   SMESH::Controls::FreeEdges::TBorders aBorders;
   myFreeEdgesPtr->GetBoreders( aBorders );
 
@@ -1237,8 +1232,6 @@ SMESH::FreeEdges::Borders* FreeEdges_i::GetBorders()
     aBorder.myPnt1 = aBord.myPntId[ 0 ];
     aBorder.myPnt2 = aBord.myPntId[ 1 ];
   }
     aBorder.myPnt1 = aBord.myPntId[ 0 ];
     aBorder.myPnt2 = aBord.myPntId[ 1 ];
   }
-
-  INFOS("FreeEdges_i::GetBorders~");
   return aResult._retn();
 }
 
   return aResult._retn();
 }
 
index 5f7d8da91714754e5fd7edaa2f580af1c5c101b5..e61aea50b597244139ffddd752a6fafaf66c47d2 100644 (file)
@@ -268,7 +268,6 @@ GEOM::GEOM_Gen_var SMESH_Gen_i::GetGeomEngine() {
 
 SMESH_Gen_i::SMESH_Gen_i()
 {
 
 SMESH_Gen_i::SMESH_Gen_i()
 {
-  INFOS( "SMESH_Gen_i::SMESH_Gen_i : default constructor" );
 }
 
 //=============================================================================
 }
 
 //=============================================================================
@@ -1876,9 +1875,9 @@ CORBA::Boolean SMESH_Gen_i::Compute( SMESH::SMESH_Mesh_ptr theMesh,
   try {
     // get mesh servant
     SMESH_Mesh_i* meshServant = dynamic_cast<SMESH_Mesh_i*>( GetServant( theMesh ).in() );
   try {
     // get mesh servant
     SMESH_Mesh_i* meshServant = dynamic_cast<SMESH_Mesh_i*>( GetServant( theMesh ).in() );
-    meshServant->Load();
     ASSERT( meshServant );
     if ( meshServant ) {
     ASSERT( meshServant );
     if ( meshServant ) {
+      meshServant->Load();
       // NPAL16168: "geometrical group edition from a submesh don't modifiy mesh computation"
       meshServant->CheckGeomModif();
       // get local TopoDS_Shape
       // NPAL16168: "geometrical group edition from a submesh don't modifiy mesh computation"
       meshServant->CheckGeomModif();
       // get local TopoDS_Shape
@@ -2157,6 +2156,7 @@ SMESH::long_array* SMESH_Gen_i::Evaluate(SMESH::SMESH_Mesh_ptr theMesh,
     SMESH_Mesh_i* meshServant = dynamic_cast<SMESH_Mesh_i*>( GetServant( theMesh ).in() );
     ASSERT( meshServant );
     if ( meshServant ) {
     SMESH_Mesh_i* meshServant = dynamic_cast<SMESH_Mesh_i*>( GetServant( theMesh ).in() );
     ASSERT( meshServant );
     if ( meshServant ) {
+      meshServant->Load();
       // NPAL16168: "geometrical group edition from a submesh don't modifiy mesh computation"
       meshServant->CheckGeomModif();
       // get local TopoDS_Shape
       // NPAL16168: "geometrical group edition from a submesh don't modifiy mesh computation"
       meshServant->CheckGeomModif();
       // get local TopoDS_Shape
@@ -2178,7 +2178,7 @@ SMESH::long_array* SMESH_Gen_i::Evaluate(SMESH::SMESH_Mesh_ptr theMesh,
           {
             SMESH_subMesh* sm = anIt->first;
             SMESH_ComputeErrorPtr& error = sm->GetComputeError();
           {
             SMESH_subMesh* sm = anIt->first;
             SMESH_ComputeErrorPtr& error = sm->GetComputeError();
-            const SMESH_Algo* algo = myGen.GetAlgo( myLocMesh, sm->GetSubShape());
+            const SMESH_Algo* algo = sm->GetAlgo();
             if ( (algo && !error.get()) || error->IsOK() )
               error.reset( new SMESH_ComputeError( COMPERR_ALGO_FAILED,"Failed to evaluate",algo));
           }
             if ( (algo && !error.get()) || error->IsOK() )
               error.reset( new SMESH_ComputeError( COMPERR_ALGO_FAILED,"Failed to evaluate",algo));
           }
@@ -2965,8 +2965,6 @@ SALOMEDS::TMPFile* SMESH_Gen_i::Save( SALOMEDS::SComponent_ptr theComponent,
                                       const char*              theURL,
                                       bool                     isMultiFile )
 {
                                       const char*              theURL,
                                       bool                     isMultiFile )
 {
-  INFOS( "SMESH_Gen_i::Save" );
-
   //  ASSERT( theComponent->GetStudy()->StudyId() == myCurrentStudy->StudyId() )
   // san -- in case <myCurrentStudy> differs from theComponent's study,
   // use that of the component
   //  ASSERT( theComponent->GetStudy()->StudyId() == myCurrentStudy->StudyId() )
   // san -- in case <myCurrentStudy> differs from theComponent's study,
   // use that of the component
@@ -3908,7 +3906,6 @@ SALOMEDS::TMPFile* SMESH_Gen_i::Save( SALOMEDS::SComponent_ptr theComponent,
   if ( !isMultiFile )
     SALOMEDS_Tool::RemoveTemporaryFiles( tmpDir.ToCString(), aFileSeq.in(), true );
 
   if ( !isMultiFile )
     SALOMEDS_Tool::RemoveTemporaryFiles( tmpDir.ToCString(), aFileSeq.in(), true );
 
-  INFOS( "SMESH_Gen_i::Save() completed" );
   return aStreamFile._retn();
 }
 
   return aStreamFile._retn();
 }
 
@@ -3975,8 +3972,6 @@ bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent,
                         const char*              theURL,
                         bool                     isMultiFile )
 {
                         const char*              theURL,
                         bool                     isMultiFile )
 {
-  INFOS( "SMESH_Gen_i::Load" );
-
   if ( theComponent->GetStudy()->StudyId() != GetCurrentStudyID() )
     SetCurrentStudy( theComponent->GetStudy() );
 
   if ( theComponent->GetStudy()->StudyId() != GetCurrentStudyID() )
     SetCurrentStudy( theComponent->GetStudy() );
 
@@ -3993,11 +3988,6 @@ bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent,
   TCollection_AsciiString tmpDir =
     ( char* )( isMultiFile ? theURL : SALOMEDS_Tool::GetTmpDir().c_str() );
 
   TCollection_AsciiString tmpDir =
     ( char* )( isMultiFile ? theURL : SALOMEDS_Tool::GetTmpDir().c_str() );
 
-  INFOS( "THE URL++++++++++++++" );
-  INFOS( theURL );
-  INFOS( "THE TMP PATH+++++++++" );
-  INFOS( tmpDir );
-
   // Convert the stream into sequence of files to process
   SALOMEDS::ListOfFileNames_var aFileSeq = SALOMEDS_Tool::PutStreamToFiles( theStream,
                                                                             tmpDir.ToCString(),
   // Convert the stream into sequence of files to process
   SALOMEDS::ListOfFileNames_var aFileSeq = SALOMEDS_Tool::PutStreamToFiles( theStream,
                                                                             tmpDir.ToCString(),
@@ -4844,7 +4834,6 @@ bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent,
     }
   }
 
     }
   }
 
-  INFOS( "SMESH_Gen_i::Load completed" );
   return true;
 }
 
   return true;
 }
 
index e623eda5f43500b2a4790efad5839e564986e65a..44a1bfdfa29bf94a4d6310356bc434b2136581c7 100644 (file)
@@ -4700,6 +4700,14 @@ SewCoincidentFreeBorders(const SMESH::CoincidentFreeBorders& freeBorders,
     }
   }
 
     }
   }
 
+  // cout << endl << "INIT" << endl;
+  // for ( size_t i = 0; i < tmp0Delems.size(); ++i )
+  // {
+  //   cout << i << " ";
+  //   if ( i % 3 == 0 ) cout << "^ ";
+  //   tmp0Delems[i]->GetNode(0)->Print( cout );
+  // }
+
   SMESH_TRY;
 
   ::SMESH_MeshEditor::Sew_Error res, ok = ::SMESH_MeshEditor::SEW_OK;
   SMESH_TRY;
 
   ::SMESH_MeshEditor::Sew_Error res, ok = ::SMESH_MeshEditor::SEW_OK;
@@ -4722,6 +4730,20 @@ SewCoincidentFreeBorders(const SMESH::CoincidentFreeBorders& freeBorders,
       if ( !n0 || !n1 || !n2 || !n3 || !n4 || !n5 )
         continue;
 
       if ( !n0 || !n1 || !n2 || !n3 || !n4 || !n5 )
         continue;
 
+      // TIDSortedElemSet emptySet, avoidSet;
+      // if ( !SMESH_MeshAlgos::FindFaceInSet( n0, n1, emptySet, avoidSet))
+      // {
+      //   cout << "WRONG 2nd 1" << endl;
+      //   n0->Print( cout );
+      //   n1->Print( cout );
+      // }
+      // if ( !SMESH_MeshAlgos::FindFaceInSet( n3, n4, emptySet, avoidSet))
+      // {
+      //   cout << "WRONG 2nd 2" << endl;
+      //   n3->Print( cout );
+      //   n4->Print( cout );
+      // }
+
       if ( !isBordToBord )
       {
         n1 = n2; // at border-to-side sewing only last side node (n1) is needed
       if ( !isBordToBord )
       {
         n1 = n2; // at border-to-side sewing only last side node (n1) is needed
@@ -4735,6 +4757,13 @@ SewCoincidentFreeBorders(const SMESH::CoincidentFreeBorders& freeBorders,
       groupSewed = ( res == ok );
 
       isBordToBord = false;
       groupSewed = ( res == ok );
 
       isBordToBord = false;
+      // cout << endl << "SEWED GROUP " << i << " PART " << iN / 3 << endl;
+      // for ( size_t t = 0; t < tmp0Delems.size(); ++t )
+      // {
+      //   cout << t << " ";
+      //   if ( t % 3 == 0 ) cout << "^ ";
+      //   tmp0Delems[t]->GetNode(0)->Print( cout );
+      // }
     }
     i0D += nodes.size();
     nbSewed += groupSewed;
     }
     i0D += nodes.size();
     nbSewed += groupSewed;
index 675b99f8a677c7110457a360c95bb2b6c521f33d..f7fcbb49308fd8db9482530e24e9856eae853c7c 100644 (file)
@@ -83,28 +83,31 @@ SMESH::SMESH_Pattern_ptr SMESH_Gen_i::GetPattern()
 //=======================================================================
 
 SMESH_Pattern_i::SMESH_Pattern_i( SMESH_Gen_i* theGen_i ):
 //=======================================================================
 
 SMESH_Pattern_i::SMESH_Pattern_i( SMESH_Gen_i* theGen_i ):
-       myGen( theGen_i )
+  myGen( theGen_i )
 {
 }
 
 //=======================================================================
 //function : getMesh
 {
 }
 
 //=======================================================================
 //function : getMesh
-//purpose  : 
+//purpose  :
 //=======================================================================
 
 ::SMESH_Mesh* SMESH_Pattern_i::getMesh( SMESH::SMESH_Mesh_ptr & theMesh )
 {
 //=======================================================================
 
 ::SMESH_Mesh* SMESH_Pattern_i::getMesh( SMESH::SMESH_Mesh_ptr & theMesh )
 {
-  SMESH_Mesh_i* anImplPtr = 
+  SMESH_Mesh_i* anImplPtr =
     dynamic_cast<SMESH_Mesh_i*>( SMESH_Gen_i::GetServant( theMesh ).in() );
   if ( anImplPtr )
     dynamic_cast<SMESH_Mesh_i*>( SMESH_Gen_i::GetServant( theMesh ).in() );
   if ( anImplPtr )
+  {
+    anImplPtr->Load();
     return & anImplPtr->GetImpl();
     return & anImplPtr->GetImpl();
+  }
 
   return 0;
 }
 
 //=======================================================================
 //function : LoadFromFile
 
   return 0;
 }
 
 //=======================================================================
 //function : LoadFromFile
-//purpose  : 
+//purpose  :
 //=======================================================================
 
 CORBA::Boolean SMESH_Pattern_i::LoadFromFile(const char* theFileContents)
 //=======================================================================
 
 CORBA::Boolean SMESH_Pattern_i::LoadFromFile(const char* theFileContents)
index bc36be444166ea43080541212dbd8aec448bbc7e..d94b05aa9e0b807e3b59d533a29980db84beb431 100644 (file)
@@ -1022,23 +1022,23 @@ namespace
    */
   //================================================================================
 
    */
   //================================================================================
 
-  bool projectVertices( SMESH_MesherHelper&                       theHelper,
-                        const SMESH_MAT2d::MedialAxis&            theMA,
-                        const vector< SMESH_MAT2d::BranchPoint >& theDivPoints,
-                        const vector< std::size_t > &             theEdgeIDs1,
-                        const vector< std::size_t > &             theEdgeIDs2,
-                        const vector< bool >&                     theIsEdgeComputed,
-                        TMAPar2NPoints &                          thePointsOnE,
-                        SinuousFace&                              theSinuFace)
+  bool projectVertices( SMESH_MesherHelper&                 theHelper,
+                        const SMESH_MAT2d::MedialAxis&      theMA,
+                        vector< SMESH_MAT2d::BranchPoint >& theDivPoints,
+                        const vector< std::size_t > &       theEdgeIDs1,
+                        const vector< std::size_t > &       theEdgeIDs2,
+                        const vector< bool >&               theIsEdgeComputed,
+                        TMAPar2NPoints &                    thePointsOnE,
+                        SinuousFace&                        theSinuFace)
   {
     SMESHDS_Mesh* meshDS = theHelper.GetMeshDS();
   {
     SMESHDS_Mesh* meshDS = theHelper.GetMeshDS();
-    const vector<TopoDS_Edge>&       theSinuEdges = theSinuFace._sinuEdges;
+    const vector< TopoDS_Edge >&     theSinuEdges = theSinuFace._sinuEdges;
     const vector< Handle(Geom_Curve) >& theCurves = theSinuFace._sinuCurves;
 
     double uMA;
     SMESH_MAT2d::BoundaryPoint bp[2];
     const SMESH_MAT2d::Branch& branch = *theMA.getBranch(0);
     const vector< Handle(Geom_Curve) >& theCurves = theSinuFace._sinuCurves;
 
     double uMA;
     SMESH_MAT2d::BoundaryPoint bp[2];
     const SMESH_MAT2d::Branch& branch = *theMA.getBranch(0);
-
+    {
       // add to thePointsOnE NodePoint's of ends of theSinuEdges
       if ( !branch.getBoundaryPoints( 0., bp[0], bp[1] ) ||
            !theMA.getBoundary().moveToClosestEdgeEnd( bp[0] )) return false;
       // add to thePointsOnE NodePoint's of ends of theSinuEdges
       if ( !branch.getBoundaryPoints( 0., bp[0], bp[1] ) ||
            !theMA.getBoundary().moveToClosestEdgeEnd( bp[0] )) return false;
@@ -1048,17 +1048,18 @@ namespace
       findVertexAndNode( np0, theSinuEdges, meshDS );
       findVertexAndNode( np1, theSinuEdges, meshDS );
       thePointsOnE.insert( make_pair( -0.1, make_pair( np0, np1 )));
       findVertexAndNode( np0, theSinuEdges, meshDS );
       findVertexAndNode( np1, theSinuEdges, meshDS );
       thePointsOnE.insert( make_pair( -0.1, make_pair( np0, np1 )));
-
+    }
     if ( !theSinuFace.IsRing() )
     {
       if ( !branch.getBoundaryPoints( 1., bp[0], bp[1] ) ||
            !theMA.getBoundary().moveToClosestEdgeEnd( bp[0] ) ||
            !theMA.getBoundary().moveToClosestEdgeEnd( bp[1] )) return false;
     if ( !theSinuFace.IsRing() )
     {
       if ( !branch.getBoundaryPoints( 1., bp[0], bp[1] ) ||
            !theMA.getBoundary().moveToClosestEdgeEnd( bp[0] ) ||
            !theMA.getBoundary().moveToClosestEdgeEnd( bp[1] )) return false;
-      np0 = bp[0]; np1 = bp[1];
+      NodePoint np0( bp[0] ), np1( bp[1] );
       findVertexAndNode( np0, theSinuEdges, meshDS );
       findVertexAndNode( np1, theSinuEdges, meshDS );
       thePointsOnE.insert( make_pair( 1.1, make_pair( np0, np1)));
     }
       findVertexAndNode( np0, theSinuEdges, meshDS );
       findVertexAndNode( np1, theSinuEdges, meshDS );
       thePointsOnE.insert( make_pair( 1.1, make_pair( np0, np1)));
     }
+
     // project theDivPoints
 
     if ( theDivPoints.empty() )
     // project theDivPoints
 
     if ( theDivPoints.empty() )
@@ -1087,7 +1088,7 @@ namespace
       if ( isVertex[0] && isVertex[1] )
         continue;
       const size_t iVert = isVertex[0] ? 0 : 1;
       if ( isVertex[0] && isVertex[1] )
         continue;
       const size_t iVert = isVertex[0] ? 0 : 1;
-      const size_t iNode   = 1 - iVert;
+      const size_t iNode = 1 - iVert;
 
       bool isOppComputed = theIsEdgeComputed[ np[ iNode ]._edgeInd ];
       if ( !isOppComputed )
 
       bool isOppComputed = theIsEdgeComputed[ np[ iNode ]._edgeInd ];
       if ( !isOppComputed )
@@ -1275,6 +1276,16 @@ namespace
             np = &get( u2NPnext->second, iSide );
             u1 = getUOnEdgeByPoint( *edgeID, np, theSinuFace );
 
             np = &get( u2NPnext->second, iSide );
             u1 = getUOnEdgeByPoint( *edgeID, np, theSinuFace );
 
+            if ( u0 == u1 )
+            {
+              if ( np->_node ) --u2NPprev;
+              else             ++u2NPnext;
+              np = &get( u2NPprev->second, iSide );
+              u0 = getUOnEdgeByPoint( *edgeID, np, theSinuFace );
+              np = &get( u2NPnext->second, iSide );
+              u1 = getUOnEdgeByPoint( *edgeID, np, theSinuFace );
+            }
+
             // distribute points and create nodes
             double du = ( u1 - u0 ) / ( sameU2NP.size() + 1 );
             double u  = u0 + du;
             // distribute points and create nodes
             double du = ( u1 - u0 ) / ( sameU2NP.size() + 1 );
             double u  = u0 + du;
@@ -1352,8 +1363,8 @@ namespace
       TMAPar2NPoints::const_iterator u2NPdist, u2NP = thePointsOnEdges.begin();
       for ( ; u2NP != thePointsOnEdges.end(); ++u2NP )
       {
       TMAPar2NPoints::const_iterator u2NPdist, u2NP = thePointsOnEdges.begin();
       for ( ; u2NP != thePointsOnEdges.end(); ++u2NP )
       {
-        SMESH_TNodeXYZ xyz( u2NP->second.first._node );
-        dist = xyz.SquareDistance( u2NP->second.second._node );
+        SMESH_TNodeXYZ        xyz( u2NP->second.first._node ); // node out
+        dist = xyz.SquareDistance( u2NP->second.second._node );// node in
         if ( dist > maxDist )
         {
           u2NPdist = u2NP;
         if ( dist > maxDist )
         {
           u2NPdist = u2NP;
@@ -1400,6 +1411,8 @@ namespace
       theFace._quad->side[ 2 ] = theFace._quad->side[ 0 ];
 
       // rotate the IN side if opposite nodes of IN and OUT sides don't match
       theFace._quad->side[ 2 ] = theFace._quad->side[ 0 ];
 
       // rotate the IN side if opposite nodes of IN and OUT sides don't match
+      if ( theFace._quad->side[ 1 ].GetUVPtStruct().empty() )
+        return false;
       const SMDS_MeshNode * nIn0 = theFace._quad->side[ 1 ].First().node;
       if ( nIn0 != nIn )
       {
       const SMDS_MeshNode * nIn0 = theFace._quad->side[ 1 ].First().node;
       if ( nIn0 != nIn )
       {
@@ -1418,6 +1431,10 @@ namespace
         uvsNew.insert( uvsNew.end(), uvsIn.begin() + i, uvsIn.end() );
         uvsNew.insert( uvsNew.end(), uvsIn.begin() + 1, uvsIn.begin() + i + 1);
         theFace._quad->side[ 1 ] = StdMeshers_FaceSide::New( uvsNew );
         uvsNew.insert( uvsNew.end(), uvsIn.begin() + i, uvsIn.end() );
         uvsNew.insert( uvsNew.end(), uvsIn.begin() + 1, uvsIn.begin() + i + 1);
         theFace._quad->side[ 1 ] = StdMeshers_FaceSide::New( uvsNew );
+
+        if ( theFace._quad->side[ 1 ].NbPoints() !=
+             theFace._quad->side[ 3 ].NbPoints())
+          return false;
       }
     } // if ( theShortEdges[0].empty() )
 
       }
     } // if ( theShortEdges[0].empty() )
 
@@ -1902,6 +1919,7 @@ bool StdMeshers_QuadFromMedialAxis_1D2D::computeQuads( SMESH_MesherHelper& theHe
 
   // create quadrangles
   bool ok;
 
   // create quadrangles
   bool ok;
+  theHelper.SetElementsOnShape( true );
   if ( nbNodesShort0 == nbNodesShort1 )
     ok = StdMeshers_Quadrangle_2D::computeQuadDominant( *theHelper.GetMesh(),
                                                         theQuad->face, theQuad );
   if ( nbNodesShort0 == nbNodesShort1 )
     ok = StdMeshers_Quadrangle_2D::computeQuadDominant( *theHelper.GetMesh(),
                                                         theQuad->face, theQuad );
index 1e35cb60b40d4393f8844ca4b2e66d7ee18d68bd..f7ac411d9a55673e25cf2f6eccb77454b0248f49 100644 (file)
@@ -3848,7 +3848,7 @@ void StdMeshers_Quadrangle_2D::updateDegenUV(FaceQuadStruct::Ptr quad)
 
     // Set number of nodes on a degenerated side to be same as on an opposite side
     // ----------------------------------------------------------------------------
 
     // Set number of nodes on a degenerated side to be same as on an opposite side
     // ----------------------------------------------------------------------------
-    for ( unsigned i = 0; i < quad->side.size(); ++i )
+    for ( size_t i = 0; i < quad->side.size(); ++i )
     {
       StdMeshers_FaceSidePtr degSide = quad->side[i];
       if ( !myHelper->IsDegenShape( degSide->EdgeID(0) ))
     {
       StdMeshers_FaceSidePtr degSide = quad->side[i];
       if ( !myHelper->IsDegenShape( degSide->EdgeID(0) ))