+//=======================================================================
+//function : makeWalls
+//purpose : create 1D and 2D elements around swept elements
+//=======================================================================
+
+static void makeWalls (SMESHDS_Mesh* aMesh,
+ TNodeOfNodeListMap & mapNewNodes,
+ TElemOfElemListMap & newElemsMap,
+ TElemOfVecOfNnlmiMap & elemNewNodesMap,
+ set<const SMDS_MeshElement*>& elemSet)
+{
+ ASSERT( newElemsMap.size() == elemNewNodesMap.size() );
+
+ // Find nodes belonging to only one initial element - sweep them to get edges.
+
+ TNodeOfNodeListMapItr nList = mapNewNodes.begin();
+ for ( ; nList != mapNewNodes.end(); nList++ )
+ {
+ const SMDS_MeshNode* node =
+ static_cast<const SMDS_MeshNode*>( nList->first );
+ SMDS_ElemIteratorPtr eIt = node->GetInverseElementIterator();
+ int nbInitElems = 0;
+ while ( eIt->more() && nbInitElems < 2 )
+ if ( elemSet.find( eIt->next() ) != elemSet.end() )
+ nbInitElems++;
+ if ( nbInitElems < 2 ) {
+ vector<TNodeOfNodeListMapItr> newNodesItVec( 1, nList );
+ list<const SMDS_MeshElement*> newEdges;
+ sweepElement( aMesh, node, newNodesItVec, newEdges );
+ }
+ }
+
+ // Make a ceiling for each element ie an equal element of last new nodes.
+ // Find free links of faces - make edges and sweep them into faces.
+
+ TElemOfElemListMap::iterator itElem = newElemsMap.begin();
+ TElemOfVecOfNnlmiMap::iterator itElemNodes = elemNewNodesMap.begin();
+ for ( ; itElem != newElemsMap.end(); itElem++, itElemNodes++ )
+ {
+ const SMDS_MeshElement* elem = itElem->first;
+ vector<TNodeOfNodeListMapItr>& vecNewNodes = itElemNodes->second;
+
+ if ( elem->GetType() == SMDSAbs_Edge )
+ {
+ // create a ceiling edge
+ aMesh->AddEdge(vecNewNodes[ 0 ]->second.back(),
+ vecNewNodes[ 1 ]->second.back() );
+ }
+ if ( elem->GetType() != SMDSAbs_Face )
+ continue;
+
+ bool hasFreeLinks = false;
+
+ set<const SMDS_MeshElement*> avoidSet;
+ avoidSet.insert( elem );
+
+ // loop on a face nodes
+ set<const SMDS_MeshNode*> aFaceLastNodes;
+ int iNode, nbNodes = vecNewNodes.size();
+ for ( iNode = 0; iNode < nbNodes; iNode++ )
+ {
+ aFaceLastNodes.insert( vecNewNodes[ iNode ]->second.back() );
+ // look for free links of a face
+ int iNext = ( iNode + 1 == nbNodes ) ? 0 : iNode + 1;
+ const SMDS_MeshNode* n1 = vecNewNodes[ iNode ]->first;
+ const SMDS_MeshNode* n2 = vecNewNodes[ iNext ]->first;
+ // check if a link is free
+ if ( ! SMESH_MeshEditor::FindFaceInSet ( n1, n2, elemSet, avoidSet ))
+ {
+ hasFreeLinks = true;
+ // make an edge and a ceiling for a new edge
+ if ( !aMesh->FindEdge( n1, n2 ))
+ aMesh->AddEdge( n1, n2 );
+ n1 = vecNewNodes[ iNode ]->second.back();
+ n2 = vecNewNodes[ iNext ]->second.back();
+ if ( !aMesh->FindEdge( n1, n2 ))
+ aMesh->AddEdge( n1, n2 );
+ }
+ }
+ // sweep free links into faces
+
+ if ( hasFreeLinks )
+ {
+ list<const SMDS_MeshElement*> & newVolumes = itElem->second;
+ int iStep, nbSteps = vecNewNodes[0]->second.size();
+ int iVol, volNb, nbVolumesByStep = newVolumes.size() / nbSteps;
+
+ set<const SMDS_MeshNode*> initNodeSet, faceNodeSet;
+ for ( iNode = 0; iNode < nbNodes; iNode++ )
+ initNodeSet.insert( vecNewNodes[ iNode ]->first );
+
+ for ( volNb = 0; volNb < nbVolumesByStep; volNb++ )
+ {
+ list<const SMDS_MeshElement*>::iterator v = newVolumes.begin();
+ iVol = 0;
+ while ( iVol++ < volNb ) v++;
+ // find indices of free faces of a volume
+ list< int > fInd;
+ SMDS_VolumeTool vTool( *v );
+ int iF, nbF = vTool.NbFaces();
+ for ( iF = 0; iF < nbF; iF ++ )
+ if (vTool.IsFreeFace( iF ) &&
+ vTool.GetFaceNodes( iF, faceNodeSet ) &&
+ initNodeSet != faceNodeSet) // except an initial face
+ fInd.push_back( iF );
+ if ( fInd.empty() )
+ continue;
+
+ // create faces for all steps
+ for ( iStep = 0; iStep < nbSteps; iStep++ )
+ {
+ vTool.Set( *v );
+ vTool.SetExternalNormal();
+ list< int >::iterator ind = fInd.begin();
+ for ( ; ind != fInd.end(); ind++ )
+ {
+ const SMDS_MeshNode** nodes = vTool.GetFaceNodes( *ind );
+ switch ( vTool.NbFaceNodes( *ind ) ) {
+ case 3:
+ aMesh->AddFace( nodes[ 0 ], nodes[ 1 ], nodes[ 2 ] ); break;
+ case 4:
+ aMesh->AddFace( nodes[ 0 ], nodes[ 1 ], nodes[ 2 ], nodes[ 3 ] ); break;
+ default:
+ {
+ int nbPolygonNodes = vTool.NbFaceNodes( *ind );
+ vector<const SMDS_MeshNode*> polygon_nodes (nbPolygonNodes);
+ for (int inode = 0; inode < nbPolygonNodes; inode++) {
+ polygon_nodes[inode] = nodes[inode];
+ }
+ aMesh->AddPolygonalFace(polygon_nodes);
+ break;
+ }
+ }
+ }
+ // go to the next volume
+ iVol = 0;
+ while ( iVol++ < nbVolumesByStep ) v++;
+ }
+ }
+ } // sweep free links into faces
+
+ // make a ceiling face with a normal external to a volume
+
+ SMDS_VolumeTool lastVol( itElem->second.back() );
+ int iF = lastVol.GetFaceIndex( aFaceLastNodes );
+ if ( iF >= 0 )
+ {
+ lastVol.SetExternalNormal();
+ const SMDS_MeshNode** nodes = lastVol.GetFaceNodes( iF );
+ switch ( lastVol.NbFaceNodes( iF ) ) {
+ case 3:
+ if (!hasFreeLinks ||
+ !aMesh->FindFace( nodes[ 0 ], nodes[ 1 ], nodes[ 2 ]))
+ aMesh->AddFace( nodes[ 0 ], nodes[ 1 ], nodes[ 2 ] );
+ break;
+ case 4:
+ if (!hasFreeLinks ||
+ !aMesh->FindFace( nodes[ 0 ], nodes[ 1 ], nodes[ 2 ], nodes[ 3 ]))
+ aMesh->AddFace( nodes[ 0 ], nodes[ 1 ], nodes[ 2 ], nodes[ 3 ] );
+ break;
+ default:
+ {
+ int nbPolygonNodes = lastVol.NbFaceNodes( iF );
+ vector<const SMDS_MeshNode*> polygon_nodes (nbPolygonNodes);
+ for (int inode = 0; inode < nbPolygonNodes; inode++) {
+ polygon_nodes[inode] = nodes[inode];
+ }
+ if (!hasFreeLinks || !aMesh->FindFace(polygon_nodes))
+ aMesh->AddPolygonalFace(polygon_nodes);
+ }
+ break;
+ }
+ }
+
+ } // loop on swept elements
+}
+