-// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2013 CEA/DEN, EDF R&D, OPEN CASCADE
//
// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
// / | / |
// N4+----------+N7 |
// | | | | HEXAHEDRON
-// | | | |
-// | | | |
// | N1+------|---+N2
// | / | /
// | / | /
{ 3, 7, 6, 2, 3 },
{ 0, 4, 7, 3, 0 }};
static int Hexa_nbN [] = { 4, 4, 4, 4, 4, 4 };
+static int Hexa_oppF[] = { 1, 0, 4, 5, 2, 3 }; // oppopsite facet indices
/*
// N8 +------+ N9
*/
static int QuadPenta_F [5][9] = { // FORWARD
{ 0, 6, 1, 7, 2, 8, 0, 0, 0 },
- { 3,11, 5, 10,4, 9, 3, 3, 3 },
+ { 3, 11,5, 10,4, 9, 3, 3, 3 },
{ 0, 12,3, 9, 4, 13,1, 6, 0 },
{ 1, 13,4, 10,5, 14,2, 7, 1 },
{ 0, 8, 2, 14,5, 11,3, 12,0 }};
static int QuadPenta_nbN [] = { 6, 6, 8, 8, 8 };
/*
-// 13
-// N5+-----+-----+N6
-// /| /|
-// 12+ | 14+ |
-// / | / |
-// N4+-----+-----+N7 | QUADRATIC
-// | | 15 | | HEXAHEDRON
-// | | | |
-// | 17+ | +18
-// | | | |
-// | | | |
-// | | | |
-// 16+ | +19 |
-// | | | |
-// | | 9 | |
-// | N1+-----+-|---+N2
-// | / | /
-// | +8 | +10
-// |/ |/
-// N0+-----+-----+N3
-// 11
+// 13
+// N5+-----+-----+N6 +-----+-----+
+// /| /| /| /|
+// 12+ | 14+ | + | +25 + |
+// / | / | / | / |
+// N4+-----+-----+N7 | QUADRATIC +-----+-----+ | Central nodes
+// | | 15 | | HEXAHEDRON | | | | of tri-quadratic
+// | | | | | | | | HEXAHEDRON
+// | 17+ | +18 | + 22+ | +
+// | | | | |21 | | |
+// | | | | | + | 26+ | + |
+// | | | | | | |23 |
+// 16+ | +19 | + | +24 + |
+// | | | | | | | |
+// | | 9 | | | | | |
+// | N1+-----+-|---+N2 | +-----+-|---+
+// | / | / | / | /
+// | +8 | +10 | + 20+ | +
+// |/ |/ |/ |/
+// N0+-----+-----+N3 +-----+-----+
+// 11
*/
static int QuadHexa_F [6][9] = { // FORWARD
{ 0, 8, 1, 9, 2, 10,3, 11,0 }, // all face normals are external,
break;
case 20:
case 27:
- if ( faceIndex <= 1 ) // top or bottom
- ind = 1 - faceIndex;
- else {
- const int nbSideFaces = myAllFacesNbNodes[0] / 2;
- ind = ( faceIndex - nbHoriFaces + nbSideFaces/2 ) % nbSideFaces + nbHoriFaces;
- }
+ ind = GetOppFaceIndexOfHex( faceIndex );
break;
default:;
}
return ind;
}
+//=======================================================================
+//function : GetOppFaceIndexOfHex
+//purpose : Return index of the opposite face of the hexahedron
+//=======================================================================
+
+int SMDS_VolumeTool::GetOppFaceIndexOfHex( int faceIndex )
+{
+ return Hexa_oppF[ faceIndex ];
+}
+
//=======================================================================
//function : IsLinked
//purpose : return true if theNode1 is linked with theNode2
//================================================================================
/*!
- * \brief check that only one volume is build on the face nodes
- *
- * If a face is shared by one of <ignoreVolumes>, it is considered free
+ * \brief Return maximal square distance between connected corner nodes
+ */
+//================================================================================
+
+double SMDS_VolumeTool::MaxLinearSize2() const
+{
+ double maxSize = -1e+100;
+ int iQ = myVolume->IsQuadratic() ? 2 : 1;
+
+ // store current face data
+ int curFace = myCurFace, nbN = myFaceNbNodes;
+ int* ind = myFaceNodeIndices;
+ myFaceNodeIndices = NULL;
+ const SMDS_MeshNode** nodes = myFaceNodes;
+ myFaceNodes = NULL;
+
+ // it seems that compute distance twice is faster than organization of a sole computing
+ myCurFace = -1;
+ for ( int iF = 0; iF < myNbFaces; ++iF )
+ {
+ setFace( iF );
+ for ( int iN = 0; iN < myFaceNbNodes; iN += iQ )
+ {
+ XYZ n1( myFaceNodes[ iN ]);
+ XYZ n2( myFaceNodes[(iN + iQ) % myFaceNbNodes]);
+ maxSize = std::max( maxSize, (n1 - n2).SquareMagnitude());
+ }
+ }
+ // restore current face data
+ myCurFace = curFace;
+ myFaceNbNodes = nbN;
+ myFaceNodeIndices = ind;
+ delete [] myFaceNodes; myFaceNodes = nodes;
+
+ return maxSize;
+}
+
+//================================================================================
+/*!
+ * \brief fast check that only one volume is build on the face nodes
*/
//================================================================================
{
const bool isFree = true;
+ if (!setFace( faceIndex ))
+ return !isFree;
+
+ const SMDS_MeshNode** nodes = GetFaceNodes( faceIndex );
+
+ // a set of facet nodes w/o medium ones and w/o nodes[0]
+ set< const SMDS_MeshElement* > nodeSet;
+ const int di = myVolume->IsQuadratic() ? 2 : 1;
+ for ( int i = di; i < myFaceNbNodes; i += di )
+ nodeSet.insert( nodes[i] );
+
+ SMDS_ElemIteratorPtr eIt = nodes[0]->GetInverseElementIterator( SMDSAbs_Volume );
+ SMDS_ElemIteratorPtr nIt;
+ while ( eIt->more() ) {
+ const SMDS_MeshElement* vol = eIt->next();
+ if ( vol != myVolume ) {
+ size_t nbShared = 0;
+ if ( const SMDS_VtkVolume* v = dynamic_cast< const SMDS_VtkVolume* >( vol ))
+ nIt = v->uniqueNodesIterator();
+ else
+ nIt = vol->nodesIterator();
+ while ( nIt->more() )
+ if (( nbShared += nodeSet.count( nIt->next() )) == nodeSet.size() )
+ {
+ 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;
+
if (!setFace( faceIndex ))
return !isFree;
//purpose : Return index of a face formed by theFaceNodes
//=======================================================================
-int SMDS_VolumeTool::GetFaceIndex( const set<const SMDS_MeshNode*>& theFaceNodes ) const
+int SMDS_VolumeTool::GetFaceIndex( const set<const SMDS_MeshNode*>& theFaceNodes,
+ const int theFaceIndexHint ) const
{
- for ( int iFace = 0; iFace < myNbFaces; iFace++ ) {
- const SMDS_MeshNode** nodes = GetFaceNodes( iFace );
- int nbFaceNodes = NbFaceNodes( iFace );
- set<const SMDS_MeshNode*> nodeSet;
- for ( int iNode = 0; iNode < nbFaceNodes; iNode++ )
- nodeSet.insert( nodes[ iNode ] );
- if ( theFaceNodes == nodeSet )
- return iFace;
+ if ( theFaceIndexHint >= 0 )
+ {
+ int nbNodes = NbFaceNodes( theFaceIndexHint );
+ if ( nbNodes == (int) theFaceNodes.size() )
+ {
+ const SMDS_MeshNode** nodes = GetFaceNodes( theFaceIndexHint );
+ while ( nbNodes )
+ if ( theFaceNodes.count( nodes[ nbNodes-1 ]))
+ --nbNodes;
+ else
+ break;
+ if ( nbNodes == 0 )
+ return theFaceIndexHint;
+ }
+ }
+ for ( int iFace = 0; iFace < myNbFaces; iFace++ )
+ {
+ if ( iFace == theFaceIndexHint )
+ continue;
+ int nbNodes = NbFaceNodes( iFace );
+ if ( nbNodes == (int) theFaceNodes.size() )
+ {
+ const SMDS_MeshNode** nodes = GetFaceNodes( iFace );
+ while ( nbNodes )
+ if ( theFaceNodes.count( nodes[ nbNodes-1 ]))
+ --nbNodes;
+ else
+ break;
+ if ( nbNodes == 0 )
+ return iFace;
+ }
}
return -1;
}