From 87c954b31cfef2bbf53487b117221c4e46bec20f Mon Sep 17 00:00:00 2001 From: eap Date: Wed, 19 Aug 2015 17:32:58 +0300 Subject: [PATCH] 52846: It is impossible to select edge in OB as reversed edge for hypothesis 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 | 50 ++- src/SMDS/SMDS_Mesh.cxx | 2 +- src/SMESH/SMESH_MeshEditor.cxx | 405 ++++++++++-------- src/SMESHDS/SMESHDS_Mesh.cxx | 14 +- src/SMESHGUI/SMESHGUI_GroupDlg.cxx | 76 ++-- src/SMESHGUI/SMESHGUI_RemoveElementsDlg.cxx | 4 + src/SMESH_SWIG/smeshBuilder.py | 22 +- .../StdMeshers_RadialQuadrangle_1D2D.cxx | 56 ++- .../StdMeshersGUI_SubShapeSelectorWdg.cxx | 94 +--- 9 files changed, 383 insertions(+), 340 deletions(-) diff --git a/src/DriverSTL/DriverSTL_W_SMDS_Mesh.cxx b/src/DriverSTL/DriverSTL_W_SMDS_Mesh.cxx index cd33b0253..3907afff8 100644 --- a/src/DriverSTL/DriverSTL_W_SMDS_Mesh.cxx +++ b/src/DriverSTL/DriverSTL_W_SMDS_Mesh.cxx @@ -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; diff --git a/src/SMDS/SMDS_Mesh.cxx b/src/SMDS/SMDS_Mesh.cxx index 58641e56b..076a102b1 100644 --- a/src/SMDS/SMDS_Mesh.cxx +++ b/src/SMDS/SMDS_Mesh.cxx @@ -2484,7 +2484,7 @@ const SMDS_MeshElement* SMDS_Mesh::FindElement (const vectorNbCornerNodes() : 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 ) diff --git a/src/SMESH/SMESH_MeshEditor.cxx b/src/SMESH/SMESH_MeshEditor.cxx index 3094dd2f3..ae309699d 100644 --- a/src/SMESH/SMESH_MeshEditor.cxx +++ b/src/SMESH/SMESH_MeshEditor.cxx @@ -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 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 nodes(nbNodes+1); - if(e->IsQuadratic()) { + if ( e->IsQuadratic() ) { const SMDS_VtkFace* F = dynamic_cast(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() )).first; + insertMapIt = insertMap.insert( make_pair( elem, list() )).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& theNodesToInsert, const bool toCreatePoly) { + if ( !theElement ) return; + + SMESHDS_Mesh *aMesh = GetMeshDS(); + vector newElems; + + if ( theElement->GetType() == SMDSAbs_Edge ) + { + theNodesToInsert.push_front( theBetweenNode1 ); + theNodesToInsert.push_back ( theBetweenNode2 ); + list::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 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 nodes( theFace->NbNodes() ); - if(theFace->IsQuadratic()) { - const SMDS_VtkFace* F = - dynamic_cast(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( 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(theFace); + if ( theFace->IsQuadratic() ) { + const SMDS_VtkFace* F = dynamic_cast(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 aNodes(nbn); - aNodes[0] = nodes[n1]; + aNodes[0 ] = nodes[n1]; aNodes[nbn-1] = nodes[n2]; list::iterator nIt = aNodesToInsert.begin(); for ( iNode = 1; nIt != aNodesToInsert.end(); nIt++ ) { aNodes[iNode++] = *nIt; } - for(i=1; iAddFace(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& 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 ); } } diff --git a/src/SMESHDS/SMESHDS_Mesh.cxx b/src/SMESHDS/SMESHDS_Mesh.cxx index d4a018b10..a66f4482f 100644 --- a/src/SMESHDS/SMESHDS_Mesh.cxx +++ b/src/SMESHDS/SMESHDS_Mesh.cxx @@ -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 removedElems; list 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::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 ); } //================================================================================ diff --git a/src/SMESHGUI/SMESHGUI_GroupDlg.cxx b/src/SMESHGUI/SMESHGUI_GroupDlg.cxx index 6176934a6..e9b683d61 100644 --- a/src/SMESHGUI/SMESHGUI_GroupDlg.cxx +++ b/src/SMESHGUI/SMESHGUI_GroupDlg.cxx @@ -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(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(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 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 diff --git a/src/SMESHGUI/SMESHGUI_RemoveElementsDlg.cxx b/src/SMESHGUI/SMESHGUI_RemoveElementsDlg.cxx index 4ad814ad6..b85c1586d 100644 --- a/src/SMESHGUI/SMESHGUI_RemoveElementsDlg.cxx +++ b/src/SMESHGUI/SMESHGUI_RemoveElementsDlg.cxx @@ -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(); diff --git a/src/SMESH_SWIG/smeshBuilder.py b/src/SMESH_SWIG/smeshBuilder.py index dfc17fb45..48e95e9a8 100644 --- a/src/SMESH_SWIG/smeshBuilder.py +++ b/src/SMESH_SWIG/smeshBuilder.py @@ -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 diff --git a/src/StdMeshers/StdMeshers_RadialQuadrangle_1D2D.cxx b/src/StdMeshers/StdMeshers_RadialQuadrangle_1D2D.cxx index aa0c542d4..204682ea9 100644 --- a/src/StdMeshers/StdMeshers_RadialQuadrangle_1D2D.cxx +++ b/src/StdMeshers/StdMeshers_RadialQuadrangle_1D2D.cxx @@ -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; } diff --git a/src/StdMeshersGUI/StdMeshersGUI_SubShapeSelectorWdg.cxx b/src/StdMeshersGUI/StdMeshersGUI_SubShapeSelectorWdg.cxx index 808abf83f..66da7722e 100644 --- a/src/StdMeshersGUI/StdMeshersGUI_SubShapeSelectorWdg.cxx +++ b/src/StdMeshersGUI/StdMeshersGUI_SubShapeSelectorWdg.cxx @@ -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 -// 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 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 ) {