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
This commit is contained in:
eap 2015-08-19 17:32:58 +03:00
parent 741a54331a
commit 87c954b31c
9 changed files with 383 additions and 340 deletions

View 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;

View 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 )

View 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 );
}
}

View 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 );
}
//================================================================================

View 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()) {
@ -2608,13 +2610,14 @@ bool SMESHGUI_GroupDlg::SetAppropriateActor()
}
// 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);
@ -2628,20 +2631,27 @@ bool SMESHGUI_GroupDlg::SetAppropriateActor()
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() ) {

View 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();

View 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

View 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;
}

View 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 ) {