mirror of
https://git.salome-platform.org/gitpub/modules/smesh.git
synced 2024-12-27 01:40:33 +05:00
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:
parent
741a54331a
commit
87c954b31c
@ -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;
|
||||
|
@ -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 )
|
||||
|
@ -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 );
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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 );
|
||||
}
|
||||
|
||||
//================================================================================
|
||||
|
@ -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
|
||||
|
@ -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();
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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 ) {
|
||||
|
Loading…
Reference in New Issue
Block a user