+
+//=============================================================================
+/*!
+ *
+ */
+//=============================================================================
+
+bool StdMeshers_Quadrangle_2D::CheckNbEdgesForEvaluate(SMESH_Mesh& aMesh,
+ const TopoDS_Shape & aShape,
+ MapShapeNbElems& aResMap,
+ std::vector<int>& aNbNodes,
+ bool& IsQuadratic)
+
+{
+ const TopoDS_Face & F = TopoDS::Face(aShape);
+
+ // verify 1 wire only, with 4 edges
+ TopoDS_Vertex V;
+ list< TopoDS_Edge > edges;
+ list< int > nbEdgesInWire;
+ int nbWire = SMESH_Block::GetOrderedEdges (F, V, edges, nbEdgesInWire);
+ if (nbWire != 1) {
+ return false;
+ }
+
+ aNbNodes.resize(4);
+
+ int nbSides = 0;
+ list< TopoDS_Edge >::iterator edgeIt = edges.begin();
+ SMESH_subMesh * sm = aMesh.GetSubMesh( *edgeIt );
+ MapShapeNbElemsItr anIt = aResMap.find(sm);
+ if(anIt==aResMap.end()) {
+ return false;
+ }
+ std::vector<int> aVec = (*anIt).second;
+ IsQuadratic = (aVec[SMDSEntity_Quad_Edge] > aVec[SMDSEntity_Edge]);
+ if ( nbEdgesInWire.front() == 3 ) { // exactly 3 edges
+ if(myTriaVertexID>0) {
+ SMESHDS_Mesh* meshDS = aMesh.GetMeshDS();
+ TopoDS_Vertex V = TopoDS::Vertex(meshDS->IndexToShape(myTriaVertexID));
+ if(!V.IsNull()) {
+ TopoDS_Edge E1,E2,E3;
+ for(; edgeIt != edges.end(); ++edgeIt) {
+ TopoDS_Edge E = TopoDS::Edge(*edgeIt);
+ TopoDS_Vertex VF, VL;
+ TopExp::Vertices(E, VF, VL, true);
+ if( VF.IsSame(V) )
+ E1 = E;
+ else if( VL.IsSame(V) )
+ E3 = E;
+ else
+ E2 = E;
+ }
+ SMESH_subMesh * sm = aMesh.GetSubMesh(E1);
+ MapShapeNbElemsItr anIt = aResMap.find(sm);
+ if(anIt==aResMap.end()) return false;
+ std::vector<int> aVec = (*anIt).second;
+ if(IsQuadratic)
+ aNbNodes[0] = (aVec[SMDSEntity_Node]-1)/2 + 2;
+ else
+ aNbNodes[0] = aVec[SMDSEntity_Node] + 2;
+ sm = aMesh.GetSubMesh(E2);
+ anIt = aResMap.find(sm);
+ if(anIt==aResMap.end()) return false;
+ aVec = (*anIt).second;
+ if(IsQuadratic)
+ aNbNodes[1] = (aVec[SMDSEntity_Node]-1)/2 + 2;
+ else
+ aNbNodes[1] = aVec[SMDSEntity_Node] + 2;
+ sm = aMesh.GetSubMesh(E3);
+ anIt = aResMap.find(sm);
+ if(anIt==aResMap.end()) return false;
+ aVec = (*anIt).second;
+ if(IsQuadratic)
+ aNbNodes[2] = (aVec[SMDSEntity_Node]-1)/2 + 2;
+ else
+ aNbNodes[2] = aVec[SMDSEntity_Node] + 2;
+ aNbNodes[3] = aNbNodes[1];
+ aNbNodes.resize(5);
+ nbSides = 4;
+ }
+ }
+ }
+ if ( nbEdgesInWire.front() == 4 ) { // exactly 4 edges
+ for(; edgeIt != edges.end(); edgeIt++) {
+ SMESH_subMesh * sm = aMesh.GetSubMesh( *edgeIt );
+ MapShapeNbElemsItr anIt = aResMap.find(sm);
+ if(anIt==aResMap.end()) {
+ return false;
+ }
+ std::vector<int> aVec = (*anIt).second;
+ if(IsQuadratic)
+ aNbNodes[nbSides] = (aVec[SMDSEntity_Node]-1)/2 + 2;
+ else
+ aNbNodes[nbSides] = aVec[SMDSEntity_Node] + 2;
+ nbSides++;
+ }
+ }
+ else if ( nbEdgesInWire.front() > 4 ) { // more than 4 edges - try to unite some
+ list< TopoDS_Edge > sideEdges;
+ while ( !edges.empty()) {
+ sideEdges.clear();
+ sideEdges.splice( sideEdges.end(), edges, edges.begin()); // edges.front() -> sideEdges.end()
+ bool sameSide = true;
+ while ( !edges.empty() && sameSide ) {
+ sameSide = SMESH_Algo::IsContinuous( sideEdges.back(), edges.front() );
+ if ( sameSide )
+ sideEdges.splice( sideEdges.end(), edges, edges.begin());
+ }
+ if ( nbSides == 0 ) { // go backward from the first edge
+ sameSide = true;
+ while ( !edges.empty() && sameSide ) {
+ sameSide = SMESH_Algo::IsContinuous( sideEdges.front(), edges.back() );
+ if ( sameSide )
+ sideEdges.splice( sideEdges.begin(), edges, --edges.end());
+ }
+ }
+ list<TopoDS_Edge>::iterator ite = sideEdges.begin();
+ aNbNodes[nbSides] = 1;
+ for(; ite!=sideEdges.end(); ite++) {
+ SMESH_subMesh * sm = aMesh.GetSubMesh( *ite );
+ MapShapeNbElemsItr anIt = aResMap.find(sm);
+ if(anIt==aResMap.end()) {
+ return false;
+ }
+ std::vector<int> aVec = (*anIt).second;
+ if(IsQuadratic)
+ aNbNodes[nbSides] += (aVec[SMDSEntity_Node]-1)/2 + 1;
+ else
+ aNbNodes[nbSides] += aVec[SMDSEntity_Node] + 1;
+ }
+ ++nbSides;
+ }
+ // issue 20222. Try to unite only edges shared by two same faces
+ if (nbSides < 4) {
+ nbSides = 0;
+ SMESH_Block::GetOrderedEdges (F, V, edges, nbEdgesInWire);
+ while ( !edges.empty()) {
+ sideEdges.clear();
+ sideEdges.splice( sideEdges.end(), edges, edges.begin());
+ bool sameSide = true;
+ while ( !edges.empty() && sameSide ) {
+ sameSide =
+ SMESH_Algo::IsContinuous( sideEdges.back(), edges.front() ) &&
+ twoEdgesMeatAtVertex( sideEdges.back(), edges.front(), aMesh );
+ if ( sameSide )
+ sideEdges.splice( sideEdges.end(), edges, edges.begin());
+ }
+ if ( nbSides == 0 ) { // go backward from the first edge
+ sameSide = true;
+ while ( !edges.empty() && sameSide ) {
+ sameSide =
+ SMESH_Algo::IsContinuous( sideEdges.front(), edges.back() ) &&
+ twoEdgesMeatAtVertex( sideEdges.front(), edges.back(), aMesh );
+ if ( sameSide )
+ sideEdges.splice( sideEdges.begin(), edges, --edges.end());
+ }
+ }
+ list<TopoDS_Edge>::iterator ite = sideEdges.begin();
+ aNbNodes[nbSides] = 1;
+ for(; ite!=sideEdges.end(); ite++) {
+ SMESH_subMesh * sm = aMesh.GetSubMesh( *ite );
+ MapShapeNbElemsItr anIt = aResMap.find(sm);
+ if(anIt==aResMap.end()) {
+ return false;
+ }
+ std::vector<int> aVec = (*anIt).second;
+ if(IsQuadratic)
+ aNbNodes[nbSides] += (aVec[SMDSEntity_Node]-1)/2 + 1;
+ else
+ aNbNodes[nbSides] += aVec[SMDSEntity_Node] + 1;
+ }
+ ++nbSides;
+ }
+ }
+ }
+ if (nbSides != 4) {
+ if ( !nbSides )
+ nbSides = nbEdgesInWire.front();
+ error(COMPERR_BAD_SHAPE, TComm("Face must have 4 sides but not ") << nbSides);
+ return false;
+ }
+
+ return true;
+}
+
+