Salome HOME
52846: It is impossible to select edge in OB as reversed edge for hypothesis
authoreap <eap@opencascade.com>
Wed, 19 Aug 2015 14:32:58 +0000 (17:32 +0300)
committereap <eap@opencascade.com>
Wed, 19 Aug 2015 14:32:58 +0000 (17:32 +0300)
52826: Radial Quadrangle algorithm meshes a quad face from which a circle was cut from but it must fail
52227: Group is not shown during edition
52780: Wrong mesh after STL re-import of a polygonal element
52825: Sew Borders does not care of segment adjacent to split faces, thus segments become non-conformal
52824: Sew Free Borders sews borders as conformal thus producing very skewed quads instead of polygons

src/DriverSTL/DriverSTL_W_SMDS_Mesh.cxx
src/SMDS/SMDS_Mesh.cxx
src/SMESH/SMESH_MeshEditor.cxx
src/SMESHDS/SMESHDS_Mesh.cxx
src/SMESHGUI/SMESHGUI_GroupDlg.cxx
src/SMESHGUI/SMESHGUI_RemoveElementsDlg.cxx
src/SMESH_SWIG/smeshBuilder.py
src/StdMeshers/StdMeshers_RadialQuadrangle_1D2D.cxx
src/StdMeshersGUI/StdMeshersGUI_SubShapeSelectorWdg.cxx

index cd33b025338f4f5f47d92dbee97d3fa09b0f3d3f..3907afff8fb6ff286212c7041811169c84ecb2f6 100644 (file)
@@ -338,7 +338,41 @@ namespace
         ++nbBadTria;
       }
     }
-    return false;
+
+    // the polygon is invalid; add triangles with positive area
+    nbBadTria = 0;
+    while ( nbBadTria < nbVertices )
+    {
+      isGoodTria = v->TriaArea() > minArea;
+      if ( isGoodTria )
+      {
+        v->GetTriaNodes( &nodes[ iN ] );
+        iN += 3;
+        v = v->Delete();
+        if ( --nbVertices == 3 )
+        {
+          // last triangle remains
+          v->GetTriaNodes( &nodes[ iN ] );
+          return true;
+        }
+        nbBadTria = 0;
+      }
+      else
+      {
+        v = v->_next;
+        ++nbBadTria;
+      }
+    }
+
+    // add all the rest triangles
+    while ( nbVertices >= 3 )
+    {
+      v->GetTriaNodes( &nodes[ iN ] );
+      iN += 3;
+      v = v->Delete();
+    }
+    
+    return true;
 
   } // triangulate()
 } // namespace
@@ -394,15 +428,15 @@ static int getTriangles( const SMDS_MeshElement*             face,
   case SMDSEntity_BiQuad_Quadrangle:
     nbTria = ( type == SMDSEntity_BiQuad_Triangle ) ? 6 : 8;
     nodes[ i++ ] = face->GetNode( nbTria );
-    while ( i < 3*(nbTria-1) )
+    for ( i = 3; i < 3*(nbTria-1); i += 3 )
     {
-      nodes[ i++ ] = nodes[ i-2 ];
-      nodes[ i++ ] = nIt->next();
-      nodes[ i++ ] = nodes[ 2 ];
+      nodes[ i+0 ] = nodes[ i-2 ];
+      nodes[ i+1 ] = nIt->next();
+      nodes[ i+2 ] = nodes[ 2 ];
     }
-    nodes[ i++ ] = nodes[ i-2 ];
-    nodes[ i++ ] = nodes[ 0 ];
-    nodes[ i++ ] = nodes[ 2 ];
+    nodes[ i+0 ] = nodes[ i-2 ];
+    nodes[ i+1 ] = nodes[ 0 ];
+    nodes[ i+2 ] = nodes[ 2 ];
     break;
   case SMDSEntity_Triangle:
     nbTria = 1;
index 58641e56bc44f284cc5c37b5f90555bc61f9a7ab..076a102b1ab6d0e4e186ce6cc3651cd26b6b8ceb 100644 (file)
@@ -2484,7 +2484,7 @@ const SMDS_MeshElement* SMDS_Mesh::FindElement (const vector<const SMDS_MeshNode
       int nbNodesToCheck = noMedium ? e->NbCornerNodes() : e->NbNodes();
       if ( nbNodesToCheck == nodes.size() )
       {
-        for ( int i = 1; e && i < nodes.size(); ++ i )
+        for ( size_t i = 1; e && i < nodes.size(); ++i )
         {
           int nodeIndex = e->GetNodeIndex( nodes[ i ]);
           if ( nodeIndex < 0 || nodeIndex >= nbNodesToCheck )
index 3094dd2f3ae37af22107b89228561f2002e5f99a..ae309699d92f8cc18edc19114bb69569ca321e75 100644 (file)
@@ -2975,7 +2975,6 @@ bool SMESH_MeshEditor::QuadToTri (TIDSortedElemSet & theElems,
         }
       AddToSameGroups( newElem1, elem, aMesh );
       AddToSameGroups( newElem2, elem, aMesh );
-      //aMesh->RemoveFreeElement(elem, aMesh->MeshElements(aShapeId), true);
       aMesh->RemoveElement( elem );
     }
 
@@ -8089,6 +8088,24 @@ static const SMDS_MeshElement* findAdjacentFace(const SMDS_MeshNode* n1,
   return SMESH_MeshAlgos::FindFaceInSet( n1, n2, elemSet, avoidSet );
 }
 
+//=======================================================================
+//function : findSegment
+//purpose  : Return a mesh segment by two nodes one of which can be medium
+//=======================================================================
+
+static const SMDS_MeshElement* findSegment(const SMDS_MeshNode* n1,
+                                           const SMDS_MeshNode* n2)
+{
+  SMDS_ElemIteratorPtr it = n1->GetInverseElementIterator( SMDSAbs_Edge );
+  while ( it->more() )
+  {
+    const SMDS_MeshElement* seg = it->next();
+    if ( seg->GetNodeIndex( n2 ) >= 0 )
+      return seg;
+  }
+  return 0;
+}
+
 //=======================================================================
 //function : FindFreeBorder
 //purpose  :
@@ -8113,7 +8130,6 @@ bool SMESH_MeshEditor::FindFreeBorder (const SMDS_MeshNode*             theFirst
   theNodes.push_back( theFirstNode );
   theNodes.push_back( theSecondNode );
 
-  //vector<const SMDS_MeshNode*> nodes;
   const SMDS_MeshNode *nIgnore = theFirstNode, *nStart = theSecondNode;
   TIDSortedElemSet foundElems;
   bool needTheLast = ( theLastNode != 0 );
@@ -8125,17 +8141,16 @@ bool SMESH_MeshEditor::FindFreeBorder (const SMDS_MeshNode*             theFirst
     // find all free border faces sharing form nStart
 
     list< const SMDS_MeshElement* > curElemList;
-    list< const SMDS_MeshNode* > nStartList;
+    list< const SMDS_MeshNode* >    nStartList;
     SMDS_ElemIteratorPtr invElemIt = nStart->GetInverseElementIterator(SMDSAbs_Face);
     while ( invElemIt->more() ) {
       const SMDS_MeshElement* e = invElemIt->next();
       if ( e == curElem || foundElems.insert( e ).second ) {
         // get nodes
         int iNode = 0, nbNodes = e->NbNodes();
-        //const SMDS_MeshNode* nodes[nbNodes+1];
         vector<const SMDS_MeshNode*> nodes(nbNodes+1);
 
-        if(e->IsQuadratic()) {
+        if ( e->IsQuadratic() ) {
           const SMDS_VtkFace* F =
             dynamic_cast<const SMDS_VtkFace*>(e);
           if (!F) throw SALOME_Exception(LOCALIZED("not an SMDS_VtkFace"));
@@ -8275,9 +8290,9 @@ SMESH_MeshEditor::SewFreeBorder (const SMDS_MeshNode* theBordFirstNode,
   //    find side nodes and elements
   // ====================================
 
-  list< const SMDS_MeshNode* > nSide[ 2 ];
+  list< const SMDS_MeshNode* >    nSide[ 2 ];
   list< const SMDS_MeshElement* > eSide[ 2 ];
-  list< const SMDS_MeshNode* >::iterator nIt[ 2 ];
+  list< const SMDS_MeshNode* >::iterator    nIt[ 2 ];
   list< const SMDS_MeshElement* >::iterator eIt[ 2 ];
 
   // Free border 1
@@ -8516,9 +8531,23 @@ SMESH_MeshEditor::SewFreeBorder (const SMDS_MeshNode* theBordFirstNode,
   int nbNodes[]  = { nSide[0].size(), nSide[1].size() };
   int maxNbNodes = Max( nbNodes[0], nbNodes[1] );
 
+  bool toMergeConformal = ( nbNodes[0] == nbNodes[1] );
+  if ( toMergeConformal && toCreatePolygons )
+  {
+    // do not merge quadrangles if polygons are OK (IPAL0052824)
+    eIt[0] = eSide[0].begin();
+    eIt[1] = eSide[1].begin();
+    bool allQuads[2] = { true, true };
+    for ( int iBord = 0; iBord < 2; iBord++ ) { // loop on 2 borders
+      for ( ; allQuads[iBord] && eIt[iBord] != eSide[iBord].end(); ++eIt[iBord] )
+        allQuads[iBord] = ( (*eIt[iBord])->NbCornerNodes() == 4 );
+    }
+    toMergeConformal = ( !allQuads[0] && !allQuads[1] );
+  }
+
   TListOfListOfNodes nodeGroupsToMerge;
-  if ( nbNodes[0] == nbNodes[1] ||
-       ( theSideIsFreeBorder && !theSideThirdNode)) {
+  if (( toMergeConformal ) ||
+      ( theSideIsFreeBorder && !theSideThirdNode )) {
 
     // all nodes are to be merged
 
@@ -8536,10 +8565,9 @@ SMESH_MeshEditor::SewFreeBorder (const SMDS_MeshNode* theBordFirstNode,
     // insert new nodes into the border and the side to get equal nb of segments
 
     // get normalized parameters of nodes on the borders
-    //double param[ 2 ][ maxNbNodes ];
-    double* param[ 2 ];
-    param[0] = new double [ maxNbNodes ];
-    param[1] = new double [ maxNbNodes ];
+    vector< double > param[ 2 ];
+    param[0].resize( maxNbNodes );
+    param[1].resize( maxNbNodes );
     int iNode, iBord;
     for ( iBord = 0; iBord < 2; iBord++ ) { // loop on 2 borders
       list< const SMDS_MeshNode* >& nodes = nSide[ iBord ];
@@ -8584,8 +8612,8 @@ SMESH_MeshEditor::SewFreeBorder (const SMDS_MeshNode* theBordFirstNode,
         if ( i[ iBord ] > 0 )
           prevParam = Max( prevParam, param[iBord][ i[iBord] - 1 ]);
       }
-      double minParam = Min( param[ 0 ][ i[0] ], param[ 1 ][ i[1] ]);
-      double maxParam = Max( param[ 0 ][ i[0] ], param[ 1 ][ i[1] ]);
+      double  minParam = Min( param[ 0 ][ i[0] ], param[ 1 ][ i[1] ]);
+      double  maxParam = Max( param[ 0 ][ i[0] ], param[ 1 ][ i[1] ]);
       double minSegLen = Min( nextParam - minParam, maxParam - prevParam );
 
       // choose to insert or to merge nodes
@@ -8609,10 +8637,10 @@ SMESH_MeshEditor::SewFreeBorder (const SMDS_MeshNode* theBordFirstNode,
         // insert
         // ------
         int intoBord = ( du < 0 ) ? 0 : 1;
-        const SMDS_MeshElement* elem = *eIt[ intoBord ];
+        const SMDS_MeshElement* elem = *eIt [ intoBord ];
         const SMDS_MeshNode*    n1   = nPrev[ intoBord ];
-        const SMDS_MeshNode*    n2   = *nIt[ intoBord ];
-        const SMDS_MeshNode*    nIns = *nIt[ 1 - intoBord ];
+        const SMDS_MeshNode*    n2   = *nIt [ intoBord ];
+        const SMDS_MeshNode*    nIns = *nIt [ 1 - intoBord ];
         if ( intoBord == 1 ) {
           // move node of the border to be on a link of elem of the side
           gp_XYZ p1 (n1->X(), n1->Y(), n1->Z());
@@ -8622,7 +8650,7 @@ SMESH_MeshEditor::SewFreeBorder (const SMDS_MeshNode* theBordFirstNode,
           GetMeshDS()->MoveNode( nIns, p.X(), p.Y(), p.Z() );
         }
         insertMapIt = insertMap.find( elem );
-        bool notFound = ( insertMapIt == insertMap.end() );
+        bool  notFound = ( insertMapIt == insertMap.end() );
         bool otherLink = ( !notFound && (*insertMapIt).second.front() != n1 );
         if ( otherLink ) {
           // insert into another link of the same element:
@@ -8632,12 +8660,11 @@ SMESH_MeshEditor::SewFreeBorder (const SMDS_MeshNode* theBordFirstNode,
           const SMDS_MeshNode* n22 = nodeList.front(); nodeList.pop_front();
           InsertNodesIntoLink( elem, n12, n22, nodeList, toCreatePolygons );
           // 2. perform insertion into the link of adjacent faces
-          while (true) {
-            const SMDS_MeshElement* adjElem = findAdjacentFace( n12, n22, elem );
-            if ( adjElem )
-              InsertNodesIntoLink( adjElem, n12, n22, nodeList, toCreatePolygons );
-            else
-              break;
+          while ( const SMDS_MeshElement* adjElem = findAdjacentFace( n12, n22, elem )) {
+            InsertNodesIntoLink( adjElem, n12, n22, nodeList, toCreatePolygons );
+          }
+          while ( const SMDS_MeshElement* seg = findSegment( n12, n22 )) {
+            InsertNodesIntoLink( seg, n12, n22, nodeList );
           }
           if (toCreatePolyedrs) {
             // perform insertion into the links of adjacent volumes
@@ -8649,8 +8676,7 @@ SMESH_MeshEditor::SewFreeBorder (const SMDS_MeshNode* theBordFirstNode,
         }
         if ( notFound || otherLink ) {
           // add element and nodes of the side into the insertMap
-          insertMapIt = insertMap.insert
-            ( TElemOfNodeListMap::value_type( elem, list<const SMDS_MeshNode*>() )).first;
+          insertMapIt = insertMap.insert( make_pair( elem, list<const SMDS_MeshNode*>() )).first;
           (*insertMapIt).second.push_back( n1 );
           (*insertMapIt).second.push_back( n2 );
         }
@@ -8684,14 +8710,14 @@ SMESH_MeshEditor::SewFreeBorder (const SMDS_MeshNode* theBordFirstNode,
 
       InsertNodesIntoLink( elem, n1, n2, nodeList, toCreatePolygons );
 
+      while ( const SMDS_MeshElement* seg = findSegment( n1, n2 )) {
+        InsertNodesIntoLink( seg, n1, n2, nodeList );
+      }
+
       if ( !theSideIsFreeBorder ) {
         // look for and insert nodes into the faces adjacent to elem
-        while (true) {
-          const SMDS_MeshElement* adjElem = findAdjacentFace( n1, n2, elem );
-          if ( adjElem )
-            InsertNodesIntoLink( adjElem, n1, n2, nodeList, toCreatePolygons );
-          else
-            break;
+        while ( const SMDS_MeshElement* adjElem = findAdjacentFace( n1, n2, elem )) {
+          InsertNodesIntoLink( adjElem, n1, n2, nodeList, toCreatePolygons );
         }
       }
       if (toCreatePolyedrs) {
@@ -8699,69 +8725,144 @@ SMESH_MeshEditor::SewFreeBorder (const SMDS_MeshNode* theBordFirstNode,
         UpdateVolumes(n1, n2, nodeList);
       }
     }
-
-    delete param[0];
-    delete param[1];
   } // end: insert new nodes
 
   MergeNodes ( nodeGroupsToMerge );
 
+
+  // Remove coincident segments
+
+  // get new segments
+  TIDSortedElemSet segments;
+  SMESH_SequenceOfElemPtr newFaces;
+  for ( int i = 1; i <= myLastCreatedElems.Length(); ++i )
+  {
+    if ( !myLastCreatedElems(i) ) continue;
+    if ( myLastCreatedElems(i)->GetType() == SMDSAbs_Edge )
+      segments.insert( segments.end(), myLastCreatedElems(i) );
+    else
+      newFaces.Append( myLastCreatedElems(i) );
+  }
+  // find coincident
+  TListOfListOfElementsID equalGroups;
+  FindEqualElements( segments, equalGroups );
+  if ( !equalGroups.empty() )
+  {
+    // remove from segments those that will be removed
+    TListOfListOfElementsID::iterator itGroups = equalGroups.begin();
+    for ( ; itGroups != equalGroups.end(); ++itGroups )
+    {
+      list< int >& group = *itGroups;
+      list< int >::iterator id = group.begin();
+      for ( ++id; id != group.end(); ++id )
+        if ( const SMDS_MeshElement* seg = GetMeshDS()->FindElement( *id ))
+          segments.erase( seg );
+    }
+    // remove equal segments
+    MergeElements( equalGroups );
+
+    // restore myLastCreatedElems
+    myLastCreatedElems = newFaces;
+    TIDSortedElemSet::iterator seg = segments.begin();
+    for ( ; seg != segments.end(); ++seg )
+      myLastCreatedElems.Append( *seg );
+  }
+
   return aResult;
 }
 
 //=======================================================================
 //function : InsertNodesIntoLink
-//purpose  : insert theNodesToInsert into theFace between theBetweenNode1
+//purpose  : insert theNodesToInsert into theElement between theBetweenNode1
 //           and theBetweenNode2 and split theElement
 //=======================================================================
 
-void SMESH_MeshEditor::InsertNodesIntoLink(const SMDS_MeshElement*     theFace,
+void SMESH_MeshEditor::InsertNodesIntoLink(const SMDS_MeshElement*     theElement,
                                            const SMDS_MeshNode*        theBetweenNode1,
                                            const SMDS_MeshNode*        theBetweenNode2,
                                            list<const SMDS_MeshNode*>& theNodesToInsert,
                                            const bool                  toCreatePoly)
 {
+  if ( !theElement ) return;
+
+  SMESHDS_Mesh *aMesh = GetMeshDS();
+  vector<const SMDS_MeshElement*> newElems;
+
+  if ( theElement->GetType() == SMDSAbs_Edge )
+  {
+    theNodesToInsert.push_front( theBetweenNode1 );
+    theNodesToInsert.push_back ( theBetweenNode2 );
+    list<const SMDS_MeshNode*>::iterator n = theNodesToInsert.begin();
+    const SMDS_MeshNode* n1 = *n;
+    for ( ++n; n != theNodesToInsert.end(); ++n )
+    {
+      const SMDS_MeshNode* n2 = *n;
+      if ( const SMDS_MeshElement* seg = aMesh->FindEdge( n1, n2 ))
+        AddToSameGroups( seg, theElement, aMesh );
+      else
+        newElems.push_back( aMesh->AddEdge ( n1, n2 ));
+      n1 = n2;
+    }
+    theNodesToInsert.pop_front();
+    theNodesToInsert.pop_back();
+
+    if ( theElement->IsQuadratic() ) // add a not split part
+    {
+      vector<const SMDS_MeshNode*> nodes( theElement->begin_nodes(),
+                                          theElement->end_nodes() );
+      int iOther = 0, nbN = nodes.size();
+      for ( ; iOther < nbN; ++iOther )
+        if ( nodes[iOther] != theBetweenNode1 &&
+             nodes[iOther] != theBetweenNode2 )
+          break;
+      if      ( iOther == 0 )
+      {
+        if ( const SMDS_MeshElement* seg = aMesh->FindEdge( nodes[0], nodes[1] ))
+          AddToSameGroups( seg, theElement, aMesh );
+        else
+          newElems.push_back( aMesh->AddEdge ( nodes[0], nodes[1] ));
+      }
+      else if ( iOther == 2 )
+      {
+        if ( const SMDS_MeshElement* seg = aMesh->FindEdge( nodes[1], nodes[2] ))
+          AddToSameGroups( seg, theElement, aMesh );
+        else
+          newElems.push_back( aMesh->AddEdge ( nodes[1], nodes[2] ));
+      }
+    }
+    // treat new elements
+    for ( size_t i = 0; i < newElems.size(); ++i )
+      if ( newElems[i] )
+      {
+        aMesh->SetMeshElementOnShape( newElems[i], theElement->getshapeId() );
+        myLastCreatedElems.Append( newElems[i] );
+      }
+    ReplaceElemInGroups( theElement, newElems, aMesh );
+    aMesh->RemoveElement( theElement );
+    return;
+
+  } // if ( theElement->GetType() == SMDSAbs_Edge )
+
+  const SMDS_MeshElement* theFace = theElement;
   if ( theFace->GetType() != SMDSAbs_Face ) return;
 
   // find indices of 2 link nodes and of the rest nodes
   int iNode = 0, il1, il2, i3, i4;
   il1 = il2 = i3 = i4 = -1;
-  //const SMDS_MeshNode* nodes[ theFace->NbNodes() ];
   vector<const SMDS_MeshNode*> nodes( theFace->NbNodes() );
 
-  if(theFace->IsQuadratic()) {
-    const SMDS_VtkFace* F =
-      dynamic_cast<const SMDS_VtkFace*>(theFace);
-    if (!F) throw SALOME_Exception(LOCALIZED("not an SMDS_VtkFace"));
-    // use special nodes iterator
-    SMDS_ElemIteratorPtr anIter = F->interlacedNodesElemIterator();
-    while( anIter->more() ) {
-      const SMDS_MeshNode* n = cast2Node(anIter->next());
-      if ( n == theBetweenNode1 )
-        il1 = iNode;
-      else if ( n == theBetweenNode2 )
-        il2 = iNode;
-      else if ( i3 < 0 )
-        i3 = iNode;
-      else
-        i4 = iNode;
-      nodes[ iNode++ ] = n;
-    }
-  }
-  else {
-    SMDS_ElemIteratorPtr nodeIt = theFace->nodesIterator();
-    while ( nodeIt->more() ) {
-      const SMDS_MeshNode* n = static_cast<const SMDS_MeshNode*>( nodeIt->next() );
-      if ( n == theBetweenNode1 )
-        il1 = iNode;
-      else if ( n == theBetweenNode2 )
-        il2 = iNode;
-      else if ( i3 < 0 )
-        i3 = iNode;
-      else
-        i4 = iNode;
-      nodes[ iNode++ ] = n;
-    }
+  SMDS_NodeIteratorPtr nodeIt = theFace->interlacedNodesIterator();
+  while ( nodeIt->more() ) {
+    const SMDS_MeshNode* n = nodeIt->next();
+    if ( n == theBetweenNode1 )
+      il1 = iNode;
+    else if ( n == theBetweenNode2 )
+      il2 = iNode;
+    else if ( i3 < 0 )
+      i3 = iNode;
+    else
+      i4 = iNode;
+    nodes[ iNode++ ] = n;
   }
   if ( il1 < 0 || il2 < 0 || i3 < 0 )
     return ;
@@ -8791,9 +8892,8 @@ void SMESH_MeshEditor::InsertNodesIntoLink(const SMDS_MeshElement*     theFace,
     // add nodes of face up to first node of link
     bool isFLN = false;
 
-    if(theFace->IsQuadratic()) {
-      const SMDS_VtkFace* F =
-        dynamic_cast<const SMDS_VtkFace*>(theFace);
+    if ( theFace->IsQuadratic() ) {
+      const SMDS_VtkFace* F = dynamic_cast<const SMDS_VtkFace*>(theFace);
       if (!F) throw SALOME_Exception(LOCALIZED("not an SMDS_VtkFace"));
       // use special nodes iterator
       SMDS_ElemIteratorPtr anIter = F->interlacedNodesElemIterator();
@@ -8835,28 +8935,12 @@ void SMESH_MeshEditor::InsertNodesIntoLink(const SMDS_MeshElement*     theFace,
       }
     }
 
-    // edit or replace the face
-    SMESHDS_Mesh *aMesh = GetMeshDS();
-
-    if (theFace->IsPoly()) {
-      aMesh->ChangePolygonNodes(theFace, poly_nodes);
-    }
-    else {
-      int aShapeId = FindShape( theFace );
-
-      SMDS_MeshElement* newElem = aMesh->AddPolygonalFace(poly_nodes);
-      myLastCreatedElems.Append(newElem);
-      if ( aShapeId && newElem )
-        aMesh->SetMeshElementOnShape( newElem, aShapeId );
-
-      aMesh->RemoveElement(theFace);
-    }
-    return;
+    // make a new face
+    newElems.push_back( aMesh->AddPolygonalFace( poly_nodes ));
   }
 
-  SMESHDS_Mesh *aMesh = GetMeshDS();
-  if( !theFace->IsQuadratic() ) {
-
+  else if ( !theFace->IsQuadratic() )
+  {
     // put aNodesToInsert between theBetweenNode1 and theBetweenNode2
     int nbLinkNodes = 2 + aNodesToInsert.size();
     //const SMDS_MeshNode* linkNodes[ nbLinkNodes ];
@@ -8905,41 +8989,32 @@ void SMESH_MeshEditor::InsertNodesIntoLink(const SMDS_MeshElement*     theFace,
     }
 
     // create new elements
-    int aShapeId = FindShape( theFace );
-
     i1 = 0; i2 = 1;
     for ( iSplit = 0; iSplit < nbSplits - 1; iSplit++ ) {
       SMDS_MeshElement* newElem = 0;
       if ( iSplit == iBestQuad )
-        newElem = aMesh->AddFace (linkNodes[ i1++ ],
-                                  linkNodes[ i2++ ],
-                                  nodes[ i3 ],
-                                  nodes[ i4 ]);
+        newElems.push_back( aMesh->AddFace (linkNodes[ i1++ ],
+                                            linkNodes[ i2++ ],
+                                            nodes[ i3 ],
+                                            nodes[ i4 ]));
       else
-        newElem = aMesh->AddFace (linkNodes[ i1++ ],
-                                  linkNodes[ i2++ ],
-                                  nodes[ iSplit < iBestQuad ? i4 : i3 ]);
-      myLastCreatedElems.Append(newElem);
-      if ( aShapeId && newElem )
-        aMesh->SetMeshElementOnShape( newElem, aShapeId );
+        newElems.push_back( aMesh->AddFace (linkNodes[ i1++ ],
+                                            linkNodes[ i2++ ],
+                                            nodes[ iSplit < iBestQuad ? i4 : i3 ]));
     }
 
-    // change nodes of theFace
     const SMDS_MeshNode* newNodes[ 4 ];
     newNodes[ 0 ] = linkNodes[ i1 ];
     newNodes[ 1 ] = linkNodes[ i2 ];
     newNodes[ 2 ] = nodes[ iSplit >= iBestQuad ? i3 : i4 ];
     newNodes[ 3 ] = nodes[ i4 ];
-    //aMesh->ChangeElementNodes( theFace, newNodes, iSplit == iBestQuad ? 4 : 3 );
-    const SMDS_MeshElement* newElem = 0;
     if (iSplit == iBestQuad)
-      newElem = aMesh->AddFace( newNodes[0], newNodes[1], newNodes[2], newNodes[3] );
+      newElems.push_back( aMesh->AddFace( newNodes[0], newNodes[1], newNodes[2], newNodes[3] ));
     else
-      newElem = aMesh->AddFace( newNodes[0], newNodes[1], newNodes[2] );
-    myLastCreatedElems.Append(newElem);
-    if ( aShapeId && newElem )
-      aMesh->SetMeshElementOnShape( newElem, aShapeId );
-} // end if(!theFace->IsQuadratic())
+      newElems.push_back( aMesh->AddFace( newNodes[0], newNodes[1], newNodes[2] ));
+
+  } // end if(!theFace->IsQuadratic())
+
   else { // theFace is quadratic
     // we have to split theFace on simple triangles and one simple quadrangle
     int tmp = il1/2;
@@ -8966,66 +9041,38 @@ void SMESH_MeshEditor::InsertNodesIntoLink(const SMDS_MeshElement*     theFace,
     //           n4           n6      n5     n4
 
     // create new elements
-    int aShapeId = FindShape( theFace );
-
     int n1,n2,n3;
-    if(nbFaceNodes==6) { // quadratic triangle
-      SMDS_MeshElement* newElem =
-        aMesh->AddFace(nodes[3],nodes[4],nodes[5]);
-      myLastCreatedElems.Append(newElem);
-      if ( aShapeId && newElem )
-        aMesh->SetMeshElementOnShape( newElem, aShapeId );
-      if(theFace->IsMediumNode(nodes[il1])) {
+    if ( nbFaceNodes == 6 ) { // quadratic triangle
+      newElems.push_back( aMesh->AddFace( nodes[3], nodes[4], nodes[5] ));
+      if ( theFace->IsMediumNode(nodes[il1]) ) {
         // create quadrangle
-        newElem = aMesh->AddFace(nodes[0],nodes[1],nodes[3],nodes[5]);
-        myLastCreatedElems.Append(newElem);
-        if ( aShapeId && newElem )
-          aMesh->SetMeshElementOnShape( newElem, aShapeId );
+        newElems.push_back( aMesh->AddFace( nodes[0], nodes[1], nodes[3], nodes[5] ));
         n1 = 1;
         n2 = 2;
         n3 = 3;
       }
       else {
         // create quadrangle
-        newElem = aMesh->AddFace(nodes[1],nodes[2],nodes[3],nodes[5]);
-        myLastCreatedElems.Append(newElem);
-        if ( aShapeId && newElem )
-          aMesh->SetMeshElementOnShape( newElem, aShapeId );
+        newElems.push_back( aMesh->AddFace( nodes[1], nodes[2], nodes[3], nodes[5] ));
         n1 = 0;
         n2 = 1;
         n3 = 5;
       }
     }
     else { // nbFaceNodes==8 - quadratic quadrangle
-      SMDS_MeshElement* newElem =
-        aMesh->AddFace(nodes[3],nodes[4],nodes[5]);
-      myLastCreatedElems.Append(newElem);
-      if ( aShapeId && newElem )
-        aMesh->SetMeshElementOnShape( newElem, aShapeId );
-      newElem = aMesh->AddFace(nodes[5],nodes[6],nodes[7]);
-      myLastCreatedElems.Append(newElem);
-      if ( aShapeId && newElem )
-        aMesh->SetMeshElementOnShape( newElem, aShapeId );
-      newElem = aMesh->AddFace(nodes[5],nodes[7],nodes[3]);
-      myLastCreatedElems.Append(newElem);
-      if ( aShapeId && newElem )
-        aMesh->SetMeshElementOnShape( newElem, aShapeId );
-      if(theFace->IsMediumNode(nodes[il1])) {
+      newElems.push_back( aMesh->AddFace( nodes[3], nodes[4], nodes[5] ));
+      newElems.push_back( aMesh->AddFace( nodes[5], nodes[6], nodes[7] ));
+      newElems.push_back( aMesh->AddFace( nodes[5], nodes[7], nodes[3] ));
+      if ( theFace->IsMediumNode( nodes[ il1 ])) {
         // create quadrangle
-        newElem = aMesh->AddFace(nodes[0],nodes[1],nodes[3],nodes[7]);
-        myLastCreatedElems.Append(newElem);
-        if ( aShapeId && newElem )
-          aMesh->SetMeshElementOnShape( newElem, aShapeId );
+        newElems.push_back( aMesh->AddFace( nodes[0], nodes[1], nodes[3], nodes[7] ));
         n1 = 1;
         n2 = 2;
         n3 = 3;
       }
       else {
         // create quadrangle
-        newElem = aMesh->AddFace(nodes[1],nodes[2],nodes[3],nodes[7]);
-        myLastCreatedElems.Append(newElem);
-        if ( aShapeId && newElem )
-          aMesh->SetMeshElementOnShape( newElem, aShapeId );
+        newElems.push_back( aMesh->AddFace( nodes[1], nodes[2], nodes[3], nodes[7] ));
         n1 = 0;
         n2 = 1;
         n3 = 7;
@@ -9033,30 +9080,34 @@ void SMESH_MeshEditor::InsertNodesIntoLink(const SMDS_MeshElement*     theFace,
     }
     // create needed triangles using n1,n2,n3 and inserted nodes
     int nbn = 2 + aNodesToInsert.size();
-    //const SMDS_MeshNode* aNodes[nbn];
     vector<const SMDS_MeshNode*> aNodes(nbn);
-    aNodes[0] = nodes[n1];
+    aNodes[0    ] = nodes[n1];
     aNodes[nbn-1] = nodes[n2];
     list<const SMDS_MeshNode*>::iterator nIt = aNodesToInsert.begin();
     for ( iNode = 1; nIt != aNodesToInsert.end(); nIt++ ) {
       aNodes[iNode++] = *nIt;
     }
-    for(i=1; i<nbn; i++) {
-      SMDS_MeshElement* newElem =
-        aMesh->AddFace(aNodes[i-1],aNodes[i],nodes[n3]);
-      myLastCreatedElems.Append(newElem);
-      if ( aShapeId && newElem )
-        aMesh->SetMeshElementOnShape( newElem, aShapeId );
-    }
+    for ( i = 1; i < nbn; i++ )
+      newElems.push_back( aMesh->AddFace( aNodes[i-1], aNodes[i], nodes[n3] ));
   }
-  // remove old face
+
+  // remove the old face
+  for ( size_t i = 0; i < newElems.size(); ++i )
+    if ( newElems[i] )
+    {
+      aMesh->SetMeshElementOnShape( newElems[i], theFace->getshapeId() );
+      myLastCreatedElems.Append( newElems[i] );
+    }
+  ReplaceElemInGroups( theFace, newElems, aMesh );
   aMesh->RemoveElement(theFace);
-}
+
+} // InsertNodesIntoLink()
 
 //=======================================================================
 //function : UpdateVolumes
 //purpose  :
 //=======================================================================
+
 void SMESH_MeshEditor::UpdateVolumes (const SMDS_MeshNode*        theBetweenNode1,
                                       const SMDS_MeshNode*        theBetweenNode2,
                                       list<const SMDS_MeshNode*>& theNodesToInsert)
@@ -9118,24 +9169,16 @@ void SMESH_MeshEditor::UpdateVolumes (const SMDS_MeshNode*        theBetweenNode
       quantities[iface] = nbFaceNodes + nbInserted;
     }
 
-    // Replace or update the volume
+    // Replace the volume
     SMESHDS_Mesh *aMesh = GetMeshDS();
 
-    if (elem->IsPoly()) {
-      aMesh->ChangePolyhedronNodes(elem, poly_nodes, quantities);
-
-    }
-    else {
-      int aShapeId = FindShape( elem );
-
-      SMDS_MeshElement* newElem =
-        aMesh->AddPolyhedralVolume(poly_nodes, quantities);
-      myLastCreatedElems.Append(newElem);
-      if (aShapeId && newElem)
-        aMesh->SetMeshElementOnShape(newElem, aShapeId);
-
-      aMesh->RemoveElement(elem);
+    if ( SMDS_MeshElement* newElem = aMesh->AddPolyhedralVolume( poly_nodes, quantities ))
+    {
+      aMesh->SetMeshElementOnShape( newElem, elem->getshapeId() );
+      myLastCreatedElems.Append( newElem );
+      ReplaceElemInGroups( elem, newElem, aMesh );
     }
+    aMesh->RemoveElement( elem );
   }
 }
 
index d4a018b10c6ba96ae17965035cb2934e9158c76d..a66f4482fe5a0f7c4523187dd12c57e5fa7c0815 100644 (file)
@@ -965,7 +965,7 @@ void SMESHDS_Mesh::RemoveElement(const SMDS_MeshElement * elt)
     if ( elt->getshapeId() > 0 )
       subMesh = MeshElements( elt->getshapeId() );
 
-    RemoveFreeElement( elt, subMesh, true);
+    RemoveFreeElement( elt, subMesh, true );
     return;
   }
  
@@ -974,7 +974,7 @@ void SMESHDS_Mesh::RemoveElement(const SMDS_MeshElement * elt)
   list<const SMDS_MeshElement *> removedElems;
   list<const SMDS_MeshElement *> removedNodes;
 
-  SMDS_Mesh::RemoveElement(elt, removedElems, removedNodes, false);
+  SMDS_Mesh::RemoveElement(elt, removedElems, removedNodes, false );
   
   removeFromContainers( this, myGroups, removedElems, false );
 }
@@ -1000,7 +1000,7 @@ void SMESHDS_Mesh::RemoveFreeElement(const SMDS_MeshElement * elt,
   myScript->RemoveElement(elt->GetID());
 
   // Rm from group
-  // Node can belong to several groups
+  // Element can belong to several groups
   if ( fromGroups && !myGroups.empty() ) {
     set<SMESHDS_GroupBase*>::iterator GrIt = myGroups.begin();
     for (; GrIt != myGroups.end(); GrIt++) {
@@ -1012,10 +1012,12 @@ void SMESHDS_Mesh::RemoveFreeElement(const SMDS_MeshElement * elt,
 
   // Rm from sub-mesh
   // Element should belong to only one sub-mesh
-  if( subMesh )
-    subMesh->RemoveElement(elt, /*deleted=*/false);
+  if ( !subMesh && elt->getshapeId() > 0 )
+    subMesh = MeshElements( elt->getshapeId() );
+  if ( subMesh )
+    subMesh->RemoveElement( elt, /*deleted=*/false );
 
-  SMDS_Mesh::RemoveFreeElement(elt);
+  SMDS_Mesh::RemoveFreeElement( elt );
 }
 
 //================================================================================
index 6176934a633b33b2b9339140e5b37a31a733d777..e9b683d611034dfb299a5a776089c4bb550e8092 100644 (file)
@@ -2571,7 +2571,7 @@ void SMESHGUI_GroupDlg::setDefaultGroupColor()
 // function : SetAppropriateActor()
 // purpose  : Find more appropriate of visible actors, set it to myActor, allow picking
 //            NPAL19389: create a group with a selection in another group.
-//            if mesh actor is not visible - find any first visible group or submesh
+//            if mesh actor is not visible - find any first visible group or sub-mesh
 //=================================================================================
 bool SMESHGUI_GroupDlg::SetAppropriateActor()
 {
@@ -2582,21 +2582,23 @@ bool SMESHGUI_GroupDlg::SetAppropriateActor()
 
   SVTK_ViewWindow* aViewWindow = SMESH::GetCurrentVtkView();
 
-  if (myGeomGroupBtn->isChecked()) {   // try current group on geometry actor
-    if (!isActor) {
-      if (!myGroupOnGeom->_is_nil()) {
-        SMESH_Actor* anActor = SMESH::FindActorByObject(myGroupOnGeom);
-        if (anActor && anActor->hasIO())
-          {
-            isActor = true;
-            if (aViewWindow && !aViewWindow->isVisible(anActor->getIO()))
-              isActor = false;
-            else
-              myActorsList.append(anActor);
-          }
-      }
+  if (myGrpTypeGroup->checkedId() > 0) {   // try current group on geometry actor
+    SMESH_Actor* anActor = 0;
+    if (!myGroupOnGeom->_is_nil())
+      anActor = SMESH::FindActorByObject(myGroupOnGeom);
+    if (!myGroupOnFilter->_is_nil())
+      anActor = SMESH::FindActorByObject(myGroupOnFilter);
+    if (anActor && anActor->hasIO())
+    {
+      isActor = true;
+      if (aViewWindow && !aViewWindow->isVisible(anActor->getIO()))
+        isActor = false;
+      else
+        myActorsList.append(anActor);
     }
-  } else {
+    return anActor;
+  }
+  else {
     // try mesh actor
     SMESH_Actor* anActor = SMESH::FindActorByObject(myMesh);
     if (anActor && anActor->hasIO()) {
@@ -2606,42 +2608,50 @@ bool SMESHGUI_GroupDlg::SetAppropriateActor()
       else
         myActorsList.append(anActor);
     }
-    
+
     // try group actor
+    SMESH_Actor* aGroupActor = 0;
     if (!isActor && !myGroup->_is_nil()) {
-      SMESH_Actor* anActor = SMESH::FindActorByObject(myGroup);
-      if (anActor && anActor->hasIO())
-        myActorsList.append(anActor);
+      aGroupActor = SMESH::FindActorByObject(myGroup);
+      if (aGroupActor && aGroupActor->hasIO())
+        myActorsList.append(aGroupActor);
     }
-    
-    // try any visible actor of group or submesh of current mesh
+
+    // try any visible actor of group or sub-mesh of current mesh
     if (aViewWindow) {
       // mesh entry
       _PTR(SObject) aSObject = SMESH::FindSObject(myMesh);
       if (aSObject) {
         CORBA::String_var meshEntry = aSObject->GetID().c_str();
         int len = strlen(meshEntry);
-        
+
         // iterate on all actors in current view window, search for
         // any visible actor, that belongs to group or submesh of current mesh
         VTK::ActorCollectionCopy aCopy(aViewWindow->getRenderer()->GetActors());
         vtkActorCollection *aCollection = aCopy.GetActors();
         int nbItems = aCollection->GetNumberOfItems();
         for (int i=0; i<nbItems && !isActor; i++)
-          {
-            SMESH_Actor *anActor = dynamic_cast<SMESH_Actor*>(aCollection->GetItemAsObject(i));
-            if (anActor && anActor->hasIO()) {
-              Handle(SALOME_InteractiveObject) anIO = anActor->getIO();
-              if (aViewWindow->isVisible(anIO)) {
-                if (anIO->hasEntry() && strncmp(anIO->getEntry(), meshEntry, len) == 0 && !myActorsList.contains(anActor) )
-                  myActorsList.append(anActor);
-              }
+        {
+          SMESH_Actor *anActor = dynamic_cast<SMESH_Actor*>(aCollection->GetItemAsObject(i));
+          if (anActor && anActor->hasIO()) {
+            Handle(SALOME_InteractiveObject) anIO = anActor->getIO();
+            if (aViewWindow->isVisible(anIO)) {
+              if (anIO->hasEntry() && strncmp(anIO->getEntry(), meshEntry, len) == 0 && !myActorsList.contains(anActor) )
+                myActorsList.append(anActor);
             }
           }
+        }
       }
     }
+
+    // Show a standalone group if nothing else is visible (IPAL52227)
+    if ( myActorsList.count() == 1 &&
+         myActorsList[0] == aGroupActor &&
+         aViewWindow && !aViewWindow->isVisible(aGroupActor->getIO()))
+      SMESH::UpdateView( aViewWindow, SMESH::eDisplay, aGroupActor->getIO()->getEntry() );
   }
-  
+
+
   if (myActorsList.count() > 0) {
     QListIterator<SMESH_Actor*> it( myActorsList );
     while ( it.hasNext() ) {
@@ -2650,10 +2660,10 @@ bool SMESHGUI_GroupDlg::SetAppropriateActor()
         anActor->SetPickable(true);
     }
   }
-  
+
   return ( isActor || (myActorsList.count() > 0) );
 }
-  
+
 //=======================================================================
 //function : setShowEntityMode
 //purpose  : make shown only entity corresponding to my type
index 4ad814ad6b3e6aa52df7f1c79fdd634d90c2cf56..b85c1586dfa0ee52f221540af894e337c1567674 100644 (file)
@@ -236,6 +236,10 @@ void SMESHGUI_RemoveElementsDlg::ClickOnApply()
     try {
       SMESH::SMESH_MeshEditor_var aMeshEditor = myMesh->GetMeshEditor();
       aResult = aMeshEditor->RemoveElements(anArrayOfIdeces.in());
+
+      if ( myActor && myMesh->NbElements() == 0 )
+        myActor->SetRepresentation(SMESH_Actor::ePoint);
+
     } catch (const SALOME::SALOME_Exception& S_ex) {
       SalomeApp_Tools::QtCatchCorbaException(S_ex);
       myEditCurrentArgument->clear();
index dfc17fb4539b2d984575fc9debfb141c12934465..48e95e9a868844038e413cd7502e8703573f0981 100644 (file)
@@ -235,7 +235,7 @@ def TreatHypoStatus(status, hypName, geomName, isAlgo, mesh):
     elif status == HYP_BAD_SUBSHAPE :
         reason = "the shape is neither the main one, nor its sub-shape, nor a valid group"
     elif status == HYP_BAD_GEOMETRY:
-        reason = "geometry mismatches the expectation of the algorithm"
+        reason = "the algorithm is not applicable to this geometry"
     elif status == HYP_HIDDEN_ALGO:
         reason = "it is hidden by an algorithm of an upper dimension, which generates elements of all dimensions"
     elif status == HYP_HIDING_ALGO:
@@ -929,7 +929,7 @@ class smeshBuilder(object, SMESH._objref_SMESH_Gen):
     ## Creates a numerical functor by its type
     #  @param theCriterion functor type - an item of SMESH.FunctorType enumeration.
     #          Type SMESH.FunctorType._items in the Python Console to see all items.
-    #          Note that not all items corresponds to numerical functors.
+    #          Note that not all items correspond to numerical functors.
     #  @return SMESH_NumericalFunctor
     #  @ingroup l1_controls
     def GetFunctor(self,theCriterion):
@@ -3172,9 +3172,9 @@ class Mesh:
     ## Fuses the neighbouring triangles into quadrangles.
     #  @param IDsOfElements The triangles to be fused.
     #  @param theCriterion  a numerical functor, in terms of enum SMESH.FunctorType, used to
-    #          choose a neighbour to fuse with.
+    #          applied to possible quadrangles to choose a neighbour to fuse with.
     #          Type SMESH.FunctorType._items in the Python Console to see all items.
-    #          Note that not all items corresponds to numerical functors.
+    #          Note that not all items correspond to numerical functors.
     #  @param MaxAngle      is the maximum angle between element normals at which the fusion
     #          is still performed; theMaxAngle is mesured in radians.
     #          Also it could be a name of variable which defines angle in degrees.
@@ -3190,10 +3190,10 @@ class Mesh:
 
     ## Fuses the neighbouring triangles of the object into quadrangles
     #  @param theObject is mesh, submesh or group
-    #  @param theCriterion is a numerical functor, in terms of enum SMESH.FunctorType, used to
-    #          choose a neighbour to fuse with.
+    #  @param theCriterion is a numerical functor, in terms of enum SMESH.FunctorType,
+    #          applied to possible quadrangles to choose a neighbour to fuse with.
     #          Type SMESH.FunctorType._items in the Python Console to see all items.
-    #          Note that not all items corresponds to numerical functors.
+    #          Note that not all items correspond to numerical functors.
     #  @param MaxAngle   a max angle between element normals at which the fusion
     #          is still performed; theMaxAngle is mesured in radians.
     #  @return TRUE in case of success, FALSE otherwise.
@@ -3208,11 +3208,11 @@ class Mesh:
 
     ## Splits quadrangles into triangles.
     #  @param IDsOfElements the faces to be splitted.
-    #  @param theCriterion   is a numerical functor, in terms of enum SMESH.FunctorType, used to
+    #  @param theCriterion is a numerical functor, in terms of enum SMESH.FunctorType, used to
     #         choose a diagonal for splitting. If @a theCriterion is None, which is a default
     #         value, then quadrangles will be split by the smallest diagonal.
     #         Type SMESH.FunctorType._items in the Python Console to see all items.
-    #         Note that not all items corresponds to numerical functors.
+    #         Note that not all items correspond to numerical functors.
     #  @return TRUE in case of success, FALSE otherwise.
     #  @ingroup l2_modif_cutquadr
     def QuadToTri (self, IDsOfElements, theCriterion = None):
@@ -3230,7 +3230,7 @@ class Mesh:
     #         choose a diagonal for splitting. If @a theCriterion is None, which is a default
     #         value, then quadrangles will be split by the smallest diagonal.
     #         Type SMESH.FunctorType._items in the Python Console to see all items.
-    #         Note that not all items corresponds to numerical functors.
+    #         Note that not all items correspond to numerical functors.
     #  @return TRUE in case of success, FALSE otherwise.
     #  @ingroup l2_modif_cutquadr
     def QuadToTriObject (self, theObject, theCriterion = None):
@@ -3283,7 +3283,7 @@ class Mesh:
     #  @param theCriterion  is a numerical functor, in terms of enum SMESH.FunctorType, used to
     #         choose a diagonal for splitting.
     #         Type SMESH.FunctorType._items in the Python Console to see all items.
-    #         Note that not all items corresponds to numerical functors.
+    #         Note that not all items correspond to numerical functors.
     #  @return 1 if 1-3 diagonal is better, 2 if 2-4
     #          diagonal is better, 0 if error occurs.
     #  @ingroup l2_modif_cutquadr
index aa0c542d45db9d79b6e1479a1a4c60373f125d35..204682ea9180c9a3a2c966fe5fcdc82f945cb131 100644 (file)
@@ -75,10 +75,12 @@ StdMeshers_RadialQuadrangle_1D2D::StdMeshers_RadialQuadrangle_1D2D(int hypId,
 
   _compatibleHypothesis.push_back("LayerDistribution2D");
   _compatibleHypothesis.push_back("NumberOfLayers2D");
-  myNbLayerHypo = 0;
-  myDistributionHypo = 0;
   _requireDiscreteBoundary = false;
   _supportSubmeshes = true;
+  _neededLowerHyps[ 1 ] = true;  // suppress warning on hiding a global 1D algo
+
+  myNbLayerHypo      = 0;
+  myDistributionHypo = 0;
 }
 
 
@@ -278,6 +280,38 @@ namespace
     }
     return nbe;
   }
+  //================================================================================
+  /*!
+   * \brief Checks if the common vertex between LinEdge's lies inside the circle
+   *  and not outside
+   *  \param [in] CircEdge - 
+   *  \param [in] LinEdge1 - 
+   *  \param [in] LinEdge2 - 
+   *  \return bool - false if there are 3 EDGEs and the corner is outside
+   */
+  //================================================================================
+
+  bool isCornerInsideCircle(const TopoDS_Edge& CircEdge,
+                            const TopoDS_Edge& LinEdge1,
+                            const TopoDS_Edge& LinEdge2)
+  {
+    if ( !CircEdge.IsNull() &&
+         !LinEdge1.IsNull() &&
+         !LinEdge2.IsNull() )
+    {
+      Handle(Geom_Circle) aCirc = Handle(Geom_Circle)::DownCast( getCurve( CircEdge ));
+      TopoDS_Vertex aCommonV;
+      if ( !aCirc.IsNull() &&
+           TopExp::CommonVertex( LinEdge1, LinEdge2, aCommonV ))
+      {
+        gp_Pnt aCommonP = BRep_Tool::Pnt( aCommonV );
+        gp_Pnt  aCenter = aCirc->Location();
+        double     dist = aCenter.Distance( aCommonP );
+        return dist < 0.1 * aCirc->Radius();
+      }
+    }
+    return true;
+  }
 
 //================================================================================
 //================================================================================
@@ -669,15 +703,17 @@ bool StdMeshers_RadialQuadrangle_1D2D::Compute(SMESH_Mesh&         aMesh,
     // segments of line
     double fp, lp;
     Handle(Geom_Circle) aCirc = Handle(Geom_Circle)::DownCast( getCurve( CircEdge ));
-    Handle(Geom_Line)  aLine1 = Handle(Geom_Line)::DownCast( getCurve( LinEdge1 ));
-    Handle(Geom_Line)  aLine2 = Handle(Geom_Line)::DownCast( getCurve( LinEdge2 ));
-    if( aCirc.IsNull() || aLine1.IsNull() || aLine2.IsNull() )
+    Handle(Geom_Line)  aLine1 = Handle(Geom_Line  )::DownCast( getCurve( LinEdge1 ));
+    Handle(Geom_Line)  aLine2 = Handle(Geom_Line  )::DownCast( getCurve( LinEdge2 ));
+    if ( aCirc.IsNull() || aLine1.IsNull() || aLine2.IsNull() )
+      return error(COMPERR_BAD_SHAPE);
+    if ( !isCornerInsideCircle( CircEdge, LinEdge1, LinEdge2 ))
       return error(COMPERR_BAD_SHAPE);
 
     if ( !algo1d->ComputeCircularEdge( aMesh, CircEdge ))
       return error( algo1d->GetComputeError() );
     map< double, const SMDS_MeshNode* > theNodes;
-    if ( !GetSortedNodesOnEdge(aMesh.GetMeshDS(),CircEdge,true,theNodes))
+    if ( !GetSortedNodesOnEdge( aMesh.GetMeshDS(), CircEdge, true, theNodes ))
       return error("Circular edge is incorrectly meshed");
 
     myHelper->IsQuadraticSubMesh( aShape );
@@ -1290,18 +1326,20 @@ bool StdMeshers_RadialQuadrangle_1D2D::Evaluate(SMESH_Mesh& aMesh,
 
 //================================================================================
 /*!
- * \brief Return true if applied compute mesh on this shape
+ * \brief Return true if the algorithm can compute mesh on this shape
  */
 //================================================================================
 
 bool StdMeshers_RadialQuadrangle_1D2D::IsApplicable( const TopoDS_Shape & aShape, bool toCheckAll )
 {
   int nbFoundFaces = 0;
-  for (TopExp_Explorer exp( aShape, TopAbs_FACE ); exp.More(); exp.Next(), ++nbFoundFaces ){
+  for (TopExp_Explorer exp( aShape, TopAbs_FACE ); exp.More(); exp.Next(), ++nbFoundFaces )
+  {
     TopoDS_Edge CircEdge, LinEdge1, LinEdge2;
     int nbe = analyseFace( exp.Current(), CircEdge, LinEdge1, LinEdge2 );
     Handle(Geom_Circle) aCirc = Handle(Geom_Circle)::DownCast( getCurve( CircEdge ));
-    bool ok = ( nbe <= 3 && nbe >= 1 && !aCirc.IsNull() );
+    bool ok = ( nbe <= 3 && nbe >= 1 && !aCirc.IsNull() &&
+                isCornerInsideCircle( CircEdge, LinEdge1, LinEdge2 ));
     if( toCheckAll  && !ok ) return false;
     if( !toCheckAll && ok  ) return true;
   }
index 808abf83f08156e25098964adfd7db39a05e8c75..66da7722e2d71ca00fd84f78368e5d70b5420925 100644 (file)
@@ -288,7 +288,9 @@ void StdMeshersGUI_SubShapeSelectorWdg::selectionIntoArgument()
                 }
               }
             }
-          } else if ( aGeomObj->GetType() == 28 /*GEOM_SUBSHAPE*/  ) {
+          } else if ( aGeomObj->GetType() == 28 /*GEOM_SUBSHAPE*/ ||
+                      myEntry == IO->getEntry() )
+          {
             GEOMBase::GetShape(aGeomObj, shape); 
             if ( !shape.IsNull() && shape.ShapeType() == mySubShType ) {
               int index = myPreviewActor->GetIndexByShape( shape );
@@ -530,9 +532,6 @@ SMESH::long_array_var StdMeshersGUI_SubShapeSelectorWdg::GetListOfIDs()
 {
   SMESH::long_array_var anArray = new SMESH::long_array;
 
-  // if ( myMainEntry != "" && myIsNotCorrected )
-  //   myListOfIDs = GetCorrectedListOfIDs( true );
-
   int size = myListOfIDs.size();
   anArray->length( size );
   for (int i = 0; i < size; i++)
@@ -575,17 +574,6 @@ bool StdMeshersGUI_SubShapeSelectorWdg::SetListOfIDs( SMESH::long_array_var theI
   return isOk;
 }
 
-//=================================================================================
-// function : SetMainShapeEntry
-// purpose  : Called to set the Entry of main shape of the mesh
-//=================================================================================
-// void StdMeshersGUI_SubShapeSelectorWdg::SetMainShapeEntry( const QString& theEntry )
-// {
-//   myMainEntry = theEntry;
-//   myMainShape = GetTopoDSByEntry( theEntry );
-//   myIsNotCorrected = true;
-// }
-
 //=================================================================================
 // function : GetMainShapeEntry
 // purpose  : Called to get the Main Object Entry
@@ -596,82 +584,6 @@ const char* StdMeshersGUI_SubShapeSelectorWdg::GetMainShapeEntry()
   return myMainEntry.c_str();
 }
 
-//=================================================================================
-// function : GetCorrectedListOfIds
-// purpose  : Called to convert the list of IDs from sub-shape IDs to main shape IDs
-//=================================================================================
-// QList<int>
-// StdMeshersGUI_SubShapeSelectorWdg::GetCorrectedListOfIDs( bool fromSubshapeToMainshape,
-//                                                           bool* isOK )
-// {
-//   if (( myMainShape.IsNull() || myGeomShape.IsNull() ) &&  fromSubshapeToMainshape )
-//     return myListOfIDs;
-//   else if (( myMainShape.IsNull() /*||*/&& myGeomShape.IsNull() ) &&  !fromSubshapeToMainshape )
-//     return mySelectedIDs;
-
-//   if ( !fromSubshapeToMainshape ) // called from SetListOfIDs
-//   {
-//     if ( myMainShape.IsNull() )
-//       std::swap( myMainShape, myGeomShape );
-//   }
-
-//   QList<int> aList;
-//   TopTools_IndexedMapOfShape aGeomMap, aMainMap;
-//   TopExp::MapShapes(myMainShape, aMainMap);
-//   if ( !myGeomShape.IsNull() )
-//     TopExp::MapShapes(myGeomShape, aGeomMap);
-
-//   bool ok = true;
-//   if ( fromSubshapeToMainshape ) // convert indexes from sub-shape to mainshape
-//   {
-//     int size = myListOfIDs.size();
-//     for (int i = 0; i < size; i++) {
-//       int index = myListOfIDs.at(i);
-//       if ( aGeomMap.Extent() < index )
-//       {
-//         ok = false;
-//       }
-//       else
-//       {
-//         TopoDS_Shape aSubShape = aGeomMap.FindKey( index );
-//         if ( mySubShType != aSubShape.ShapeType() )
-//           ok = false;
-//         if ( !aMainMap.Contains( aSubShape ))
-//           ok = false;
-//         else
-//           index = aMainMap.FindIndex( aSubShape );
-//       }
-//       aList.append( index );
-//     }
-//     myIsNotCorrected = false;
-//   }
-//   else // convert indexes from main shape to sub-shape, or just check indices
-//   {
-//     int size = mySelectedIDs.size();
-//     for (int i = 0; i < size; i++) {
-//       int index = mySelectedIDs.at(i);
-//       if ( aMainMap.Extent() < index )
-//       {
-//         ok = false;
-//       }
-//       else
-//       {
-//         TopoDS_Shape aSubShape = aMainMap.FindKey( index );
-//         if ( mySubShType != aSubShape.ShapeType() )
-//           ok = false;
-//         if ( !aGeomMap.Contains( aSubShape ) && !aGeomMap.IsEmpty() )
-//           ok = false;
-//         else
-//           index = aGeomMap.FindIndex( aSubShape );
-//       }
-//       aList.append( index );
-//     }
-//   }
-//   if ( isOK ) *isOK = ok;
-
-//   return aList;
-// }
-
 void StdMeshersGUI_SubShapeSelectorWdg::updateButtons()
 {
   if ( myPreviewActor ) {