+ faces.clear();
+ SaveFacet savedFacet( myCurFace );
+ if ( IsPoly() )
+ for ( int iF = 0; iF < NbFaces(); ++iF ) {
+ if ( setFace( iF ))
+ if ( const SMDS_MeshElement* face = SMDS_Mesh::FindFace( myCurFace.myNodes ))
+ faces.push_back( face );
+ }
+ else
+ for ( int iF = 0; iF < NbFaces(); ++iF ) {
+ const SMDS_MeshFace* face = 0;
+ const SMDS_MeshNode** nodes = GetFaceNodes( iF );
+ switch ( NbFaceNodes( iF )) {
+ case 3:
+ face = SMDS_Mesh::FindFace( nodes[0], nodes[1], nodes[2] ); break;
+ case 4:
+ face = SMDS_Mesh::FindFace( nodes[0], nodes[1], nodes[2], nodes[3] ); break;
+ case 6:
+ face = SMDS_Mesh::FindFace( nodes[0], nodes[1], nodes[2],
+ nodes[3], nodes[4], nodes[5]); break;
+ case 8:
+ face = SMDS_Mesh::FindFace( nodes[0], nodes[1], nodes[2], nodes[3],
+ nodes[4], nodes[5], nodes[6], nodes[7]); break;
+ }
+ if ( face )
+ faces.push_back( face );
+ }
+ return faces.size();
+}
+
+
+//================================================================================
+/*!
+ * \brief Fill vector with boundary edges existing in the mesh
+ * \param edges - vector of found edges
+ * \retval int - nb of found faces
+ */
+//================================================================================
+
+int SMDS_VolumeTool::GetAllExistingEdges(vector<const SMDS_MeshElement*> & edges) const
+{
+ edges.clear();
+ edges.reserve( myVolumeNodes.size() * 2 );
+ for ( size_t i = 0; i < myVolumeNodes.size()-1; ++i ) {
+ for ( size_t j = i + 1; j < myVolumeNodes.size(); ++j ) {
+ if ( IsLinked( i, j )) {
+ const SMDS_MeshElement* edge =
+ SMDS_Mesh::FindEdge( myVolumeNodes[i], myVolumeNodes[j] );
+ if ( edge )
+ edges.push_back( edge );
+ }
+ }
+ }
+ return edges.size();
+}
+
+//================================================================================
+/*!
+ * \brief Return minimal square distance between connected corner nodes
+ */
+//================================================================================
+
+double SMDS_VolumeTool::MinLinearSize2() const
+{
+ double minSize = 1e+100;
+ int iQ = myVolume->IsQuadratic() ? 2 : 1;
+
+ SaveFacet savedFacet( myCurFace );
+
+ // it seems that compute distance twice is faster than organization of a sole computing
+ myCurFace.myIndex = -1;
+ for ( int iF = 0; iF < myNbFaces; ++iF )
+ {
+ setFace( iF );
+ for ( int iN = 0; iN < myCurFace.myNbNodes; iN += iQ )
+ {
+ XYZ n1( myCurFace.myNodes[ iN ]);
+ XYZ n2( myCurFace.myNodes[(iN + iQ) % myCurFace.myNbNodes]);
+ minSize = std::min( minSize, (n1 - n2).SquareMagnitude());
+ }
+ }
+
+ return minSize;
+}
+
+//================================================================================
+/*!
+ * \brief Return maximal square distance between connected corner nodes
+ */
+//================================================================================
+
+double SMDS_VolumeTool::MaxLinearSize2() const
+{
+ double maxSize = -1e+100;
+ int iQ = myVolume->IsQuadratic() ? 2 : 1;
+
+ SaveFacet savedFacet( myCurFace );
+
+ // it seems that compute distance twice is faster than organization of a sole computing
+ myCurFace.myIndex = -1;
+ for ( int iF = 0; iF < myNbFaces; ++iF )
+ {
+ setFace( iF );
+ for ( int iN = 0; iN < myCurFace.myNbNodes; iN += iQ )
+ {
+ XYZ n1( myCurFace.myNodes[ iN ]);
+ XYZ n2( myCurFace.myNodes[(iN + iQ) % myCurFace.myNbNodes]);
+ maxSize = std::max( maxSize, (n1 - n2).SquareMagnitude());
+ }
+ }
+
+ return maxSize;
+}
+
+//================================================================================
+/*!
+ * \brief fast check that only one volume is build on the face nodes
+ * This check is valid for conformal meshes only
+ */
+//================================================================================
+
+bool SMDS_VolumeTool::IsFreeFace( int faceIndex, const SMDS_MeshElement** otherVol/*=0*/ ) const
+{
+ const bool isFree = true;
+
+ if ( !setFace( faceIndex ))
+ return !isFree;
+
+ const SMDS_MeshNode** nodes = GetFaceNodes( faceIndex );
+
+ const int di = myVolume->IsQuadratic() ? 2 : 1;
+ const int nbN = ( myCurFace.myNbNodes/di <= 4 && !IsPoly()) ? 3 : myCurFace.myNbNodes/di; // nb nodes to check
+
+ SMDS_ElemIteratorPtr eIt = nodes[0]->GetInverseElementIterator( SMDSAbs_Volume );
+ while ( eIt->more() )
+ {
+ const SMDS_MeshElement* vol = eIt->next();
+ if ( vol == myVolume )
+ continue;
+ int iN;
+ for ( iN = 1; iN < nbN; ++iN )
+ if ( vol->GetNodeIndex( nodes[ iN*di ]) < 0 )
+ break;
+ if ( iN == nbN ) // nbN nodes are shared with vol
+ {
+ // if ( vol->IsPoly() || vol->NbFaces() > 6 ) // vol is polyhed or hex prism
+ // {
+ // int nb = myCurFace.myNbNodes;
+ // if ( myVolume->GetEntityType() != vol->GetEntityType() )
+ // nb -= ( GetCenterNodeIndex(0) > 0 );
+ // set<const SMDS_MeshNode*> faceNodes( nodes, nodes + nb );
+ // if ( SMDS_VolumeTool( vol ).GetFaceIndex( faceNodes ) < 0 )
+ // continue;
+ // }
+ if ( otherVol ) *otherVol = vol;
+ return !isFree;
+ }
+ }
+ if ( otherVol ) *otherVol = 0;
+ return isFree;
+}
+
+//================================================================================
+/*!
+ * \brief Thorough check that only one volume is build on the face nodes
+ */
+//================================================================================
+
+bool SMDS_VolumeTool::IsFreeFaceAdv( int faceIndex, const SMDS_MeshElement** otherVol/*=0*/ ) const
+{
+ const bool isFree = true;