0021692: EDF 2314 : Hexaedron failure

Fix for the case where topologically neighboring faces composing a box
side are not neighboring within the list of sub-shapes of a box
This commit is contained in:
eap 2012-07-04 14:55:48 +00:00
parent 889cfca686
commit 85abc582be
2 changed files with 229 additions and 249 deletions

View File

@ -59,8 +59,8 @@
#ifdef _DEBUG_ #ifdef _DEBUG_
// #define DEB_FACES //#define DEB_FACES
// #define DEB_GRID //#define DEB_GRID
#define DUMP_VERT(msg,V) \ #define DUMP_VERT(msg,V) \
// { TopoDS_Vertex v = V; gp_Pnt p = BRep_Tool::Pnt(v);\ // { TopoDS_Vertex v = V; gp_Pnt p = BRep_Tool::Pnt(v);\
// cout << msg << "( "<< p.X()<<", "<<p.Y()<<", "<<p.Z()<<" )"<<endl;} // cout << msg << "( "<< p.X()<<", "<<p.Y()<<", "<<p.Z()<<" )"<<endl;}
@ -104,11 +104,12 @@ public:
_FaceSide(const list<TopoDS_Edge>& edges); _FaceSide(const list<TopoDS_Edge>& edges);
_FaceSide* GetSide(const int i); _FaceSide* GetSide(const int i);
const _FaceSide* GetSide(const int i) const; const _FaceSide* GetSide(const int i) const;
int size() { return myChildren.size(); } int size() const { return myChildren.size(); }
int NbVertices() const; int NbVertices() const;
TopoDS_Vertex FirstVertex() const; TopoDS_Vertex FirstVertex() const;
TopoDS_Vertex LastVertex() const; TopoDS_Vertex LastVertex() const;
TopoDS_Vertex Vertex(int i) const; TopoDS_Vertex Vertex(int i) const;
TopoDS_Edge Edge(int i) const;
bool Contain( const _FaceSide& side, int* which=0 ) const; bool Contain( const _FaceSide& side, int* which=0 ) const;
bool Contain( const TopoDS_Vertex& vertex ) const; bool Contain( const TopoDS_Vertex& vertex ) const;
void AppendSide( const _FaceSide& side ); void AppendSide( const _FaceSide& side );
@ -127,7 +128,6 @@ private:
list< _FaceSide > myChildren; list< _FaceSide > myChildren;
int myNbChildren; int myNbChildren;
//set<const TopoDS_TShape*> myVertices;
TopTools_MapOfShape myVertices; TopTools_MapOfShape myVertices;
EQuadSides myID; // debug EQuadSides myID; // debug
@ -154,14 +154,16 @@ public: //** Methods to find and orient faces of 6 sides of the box **//
//!< Try to set the side as bottom hirizontal side //!< Try to set the side as bottom hirizontal side
bool SetBottomSide(const _FaceSide& side, int* sideIndex=0); bool SetBottomSide(const _FaceSide& side, int* sideIndex=0);
//!< Return face adjacent to i-th side of this face //!< Return face adjacent to zero-based i-th side of this face
_QuadFaceGrid* FindAdjacentForSide(int i, vector<_QuadFaceGrid>& faces) const; // (0<i<4) _QuadFaceGrid* FindAdjacentForSide(int i, list<_QuadFaceGrid>& faces, EBoxSides id) const;
//!< Reverse edges in order to have the bottom edge going along axes of the unit box //!< Reverse edges in order to have the bottom edge going along axes of the unit box
void ReverseEdges(/*int e1, int e2*/); void ReverseEdges(/*int e1, int e2*/);
bool IsComplex() const { return !myChildren.empty(); } bool IsComplex() const { return !myChildren.empty(); }
int NbChildren() const { return myChildren.size(); }
typedef SMDS_SetIterator< const _QuadFaceGrid&, TChildren::const_iterator > TChildIterator; typedef SMDS_SetIterator< const _QuadFaceGrid&, TChildren::const_iterator > TChildIterator;
TChildIterator GetChildren() const TChildIterator GetChildren() const
@ -178,6 +180,9 @@ public: //** Loading and access to mesh **//
//!< Return number of segments on the vertical sides //!< Return number of segments on the vertical sides
int GetNbVertSegments(SMESH_Mesh& mesh, bool withBrothers=false) const; int GetNbVertSegments(SMESH_Mesh& mesh, bool withBrothers=false) const;
//!< Return edge on the hirizontal bottom sides
int GetHoriEdges(vector<TopoDS_Edge> & edges) const;
//!< Return a node by its position //!< Return a node by its position
const SMDS_MeshNode* GetNode(int iHori, int iVert) const; const SMDS_MeshNode* GetNode(int iHori, int iVert) const;
@ -270,35 +275,42 @@ bool StdMeshers_CompositeHexa_3D::CheckHypothesis(SMESH_Mesh& aMesh,
//================================================================================ //================================================================================
/*! /*!
* \brief Computes hexahedral mesh on a box with composite sides * \brief Tries to find 6 sides of a box
* \param aMesh - mesh to compute
* \param aShape - shape to mesh
* \retval bool - succes sign
*/ */
//================================================================================ //================================================================================
bool StdMeshers_CompositeHexa_3D::Compute(SMESH_Mesh& theMesh, bool StdMeshers_CompositeHexa_3D::findBoxFaces( const TopoDS_Shape& shape,
const TopoDS_Shape& theShape) list< _QuadFaceGrid >& boxFaces,
_QuadFaceGrid * & fBottom,
_QuadFaceGrid * & fTop,
_QuadFaceGrid * & fFront,
_QuadFaceGrid * & fBack,
_QuadFaceGrid * & fLeft,
_QuadFaceGrid * & fRight)
{ {
SMESH_MesherHelper helper( theMesh ); list< _QuadFaceGrid >::iterator boxFace;
_quadraticMesh = helper.IsQuadraticSubMesh( theShape );
helper.SetElementsOnShape( true );
// -------------------------
// Try to find 6 side faces
// -------------------------
vector< _QuadFaceGrid > boxFaces; boxFaces.reserve( 6 );
TopExp_Explorer exp; TopExp_Explorer exp;
int iFace, nbFaces = 0; int nbFaces = 0;
for ( exp.Init(theShape, TopAbs_FACE); exp.More(); exp.Next(), ++nbFaces ) for ( exp.Init( shape, TopAbs_FACE); exp.More(); exp.Next(), ++nbFaces )
{ {
_QuadFaceGrid f; _QuadFaceGrid f;
if ( !f.Init( TopoDS::Face( exp.Current() ))) if ( !f.Init( TopoDS::Face( exp.Current() )))
return error (COMPERR_BAD_SHAPE); return error (COMPERR_BAD_SHAPE);
bool isContinuous = false;
for ( int i=0; i < boxFaces.size() && !isContinuous; ++i ) _QuadFaceGrid* prevContinuous = 0;
isContinuous = boxFaces[ i ].AddContinuousFace( f ); for ( boxFace = boxFaces.begin(); boxFace != boxFaces.end(); ++boxFace )
if ( !isContinuous ) {
if ( prevContinuous )
{
if ( prevContinuous->AddContinuousFace( *boxFace ))
boxFace = --boxFaces.erase( boxFace );
}
else if ( boxFace->AddContinuousFace( f ))
{
prevContinuous = & (*boxFace);
}
}
if ( !prevContinuous )
boxFaces.push_back( f ); boxFaces.push_back( f );
} }
// Check what we have // Check what we have
@ -309,29 +321,30 @@ bool StdMeshers_CompositeHexa_3D::Compute(SMESH_Mesh& theMesh,
if ( boxFaces.size() != 6 && nbFaces == 6 ) { // strange ordinary box with continuous faces if ( boxFaces.size() != 6 && nbFaces == 6 ) { // strange ordinary box with continuous faces
boxFaces.resize( 6 ); boxFaces.resize( 6 );
iFace = 0; boxFace = boxFaces.begin();
for ( exp.Init(theShape, TopAbs_FACE); exp.More(); exp.Next(), ++iFace ) for ( exp.Init( shape, TopAbs_FACE); exp.More(); exp.Next(), ++boxFace )
boxFaces[ iFace ].Init( TopoDS::Face( exp.Current() ) ); boxFace->Init( TopoDS::Face( exp.Current() ) );
} }
// ---------------------------------------- // ----------------------------------------
// Find out position of faces within a box // Find out position of faces within a box
// ---------------------------------------- // ----------------------------------------
_QuadFaceGrid *fBottom, *fTop, *fFront, *fBack, *fLeft, *fRight;
// start from a bottom face // start from a bottom face
fBottom = &boxFaces[0]; fBottom = &boxFaces.front();
fBottom->SetID( B_BOTTOM );
// find vertical faces // find vertical faces
fFront = fBottom->FindAdjacentForSide( Q_BOTTOM, boxFaces ); fFront = fBottom->FindAdjacentForSide( Q_BOTTOM, boxFaces, B_FRONT );
fLeft = fBottom->FindAdjacentForSide( Q_RIGHT, boxFaces ); fLeft = fBottom->FindAdjacentForSide( Q_RIGHT, boxFaces, B_LEFT );
fBack = fBottom->FindAdjacentForSide( Q_TOP, boxFaces ); fBack = fBottom->FindAdjacentForSide( Q_TOP, boxFaces, B_BACK );
fRight = fBottom->FindAdjacentForSide( Q_LEFT, boxFaces ); fRight = fBottom->FindAdjacentForSide( Q_LEFT, boxFaces, B_RIGHT );
// check the found // check the found
if ( !fFront || !fBack || !fLeft || !fRight ) if ( !fFront || !fBack || !fLeft || !fRight )
return error(COMPERR_BAD_SHAPE); return error(COMPERR_BAD_SHAPE);
// top face // find a top face
fTop = 0; fTop = 0;
for ( int i=1; i < boxFaces.size() && !fTop; ++i ) { for ( boxFace = ++boxFaces.begin(); boxFace != boxFaces.end() && !fTop; ++boxFace )
fTop = & boxFaces[ i ]; {
fTop = & (*boxFace);
fTop->SetID( B_TOP );
if ( fTop==fFront || fTop==fLeft || fTop==fBack || fTop==fRight ) if ( fTop==fFront || fTop==fLeft || fTop==fBack || fTop==fRight )
fTop = 0; fTop = 0;
} }
@ -351,18 +364,39 @@ bool StdMeshers_CompositeHexa_3D::Compute(SMESH_Mesh& theMesh,
if ( !fTop ) if ( !fTop )
return error(COMPERR_BAD_SHAPE); return error(COMPERR_BAD_SHAPE);
fBottom->SetID( B_BOTTOM );
fBack ->SetID( B_BACK );
fLeft ->SetID( B_LEFT );
fFront ->SetID( B_FRONT );
fRight ->SetID( B_RIGHT );
fTop ->SetID( B_TOP );
// orient bottom egde of faces along axes of the unit box // orient bottom egde of faces along axes of the unit box
fBottom->ReverseEdges(); fBottom->ReverseEdges();
fBack ->ReverseEdges(); fBack ->ReverseEdges();
fLeft ->ReverseEdges(); fLeft ->ReverseEdges();
return true;
}
//================================================================================
/*!
* \brief Computes hexahedral mesh on a box with composite sides
* \param aMesh - mesh to compute
* \param aShape - shape to mesh
* \retval bool - succes sign
*/
//================================================================================
bool StdMeshers_CompositeHexa_3D::Compute(SMESH_Mesh& theMesh,
const TopoDS_Shape& theShape)
{
SMESH_MesherHelper helper( theMesh );
_quadraticMesh = helper.IsQuadraticSubMesh( theShape );
helper.SetElementsOnShape( true );
// -------------------------
// Try to find 6 side faces
// -------------------------
list< _QuadFaceGrid > boxFaceContainer;
_QuadFaceGrid *fBottom, *fTop, *fFront, *fBack, *fLeft, *fRight;
if ( ! findBoxFaces( theShape, boxFaceContainer,
fBottom, fTop, fFront, fBack, fLeft, fRight))
return false;
// ------------------------------------------ // ------------------------------------------
// Fill columns of nodes with existing nodes // Fill columns of nodes with existing nodes
// ------------------------------------------ // ------------------------------------------
@ -485,7 +519,7 @@ bool StdMeshers_CompositeHexa_3D::Compute(SMESH_Mesh& theMesh,
} }
} }
// faces no more needed, free memory // faces no more needed, free memory
boxFaces.clear(); boxFaceContainer.clear();
// ---------------- // ----------------
// Add hexahedrons // Add hexahedrons
@ -507,208 +541,85 @@ bool StdMeshers_CompositeHexa_3D::Compute(SMESH_Mesh& theMesh,
return true; return true;
} }
//=======================================================================
//function : GetNb2d
//purpose : auxilary for Evaluate
//=======================================================================
int GetNb2d(_QuadFaceGrid* QFG, SMESH_Mesh& theMesh,
MapShapeNbElems& aResMap)
{
int nb2d = 0;
_QuadFaceGrid::TChildIterator aCI = QFG->GetChildren();
while( aCI.more() ) {
const _QuadFaceGrid& currChild = aCI.next();
SMESH_subMesh *sm = theMesh.GetSubMesh(currChild.GetFace());
if( sm ) {
MapShapeNbElemsItr anIt = aResMap.find(sm);
if( anIt == aResMap.end() ) continue;
std::vector<int> aVec = (*anIt).second;
nb2d += Max(aVec[SMDSEntity_Quadrangle],aVec[SMDSEntity_Quad_Quadrangle]);
}
}
return nb2d;
}
//================================================================================ //================================================================================
/*! /*!
* Evaluate * Evaluate
*/ */
//================================================================================ //================================================================================
bool StdMeshers_CompositeHexa_3D::Evaluate(SMESH_Mesh& theMesh, bool StdMeshers_CompositeHexa_3D::Evaluate(SMESH_Mesh& theMesh,
const TopoDS_Shape& theShape, const TopoDS_Shape& theShape,
MapShapeNbElems& aResMap) MapShapeNbElems& aResMap)
{ {
SMESH_MesherHelper aTool(theMesh);
bool _quadraticMesh = aTool.IsQuadraticSubMesh(theShape);
// ------------------------- // -------------------------
// Try to find 6 side faces // Try to find 6 side faces
// ------------------------- // -------------------------
vector< _QuadFaceGrid > boxFaces; boxFaces.reserve( 6 ); list< _QuadFaceGrid > boxFaceContainer;
TopExp_Explorer exp;
int iFace, nbFaces = 0;
for ( exp.Init(theShape, TopAbs_FACE); exp.More(); exp.Next(), ++nbFaces )
{
_QuadFaceGrid f;
if ( !f.Init( TopoDS::Face( exp.Current() )))
//return error (COMPERR_BAD_SHAPE);
return false;
bool isContinuous = false;
for ( int i=0; i < boxFaces.size() && !isContinuous; ++i )
isContinuous = boxFaces[ i ].AddContinuousFace( f );
if ( !isContinuous )
boxFaces.push_back( f );
}
// Check what we have
if ( boxFaces.size() != 6 && nbFaces != 6)
//return error
// (COMPERR_BAD_SHAPE,
// SMESH_Comment("Can't find 6 sides of a box. Number of found sides - ")<<boxFaces.size());
return false;
if ( boxFaces.size() != 6 && nbFaces == 6 ) { // strange ordinary box with continuous faces
boxFaces.resize( 6 );
iFace = 0;
for ( exp.Init(theShape, TopAbs_FACE); exp.More(); exp.Next(), ++iFace )
boxFaces[ iFace ].Init( TopoDS::Face( exp.Current() ) );
}
// ----------------------------------------
// Find out position of faces within a box
// ----------------------------------------
_QuadFaceGrid *fBottom, *fTop, *fFront, *fBack, *fLeft, *fRight; _QuadFaceGrid *fBottom, *fTop, *fFront, *fBack, *fLeft, *fRight;
// start from a bottom face if ( ! findBoxFaces( theShape, boxFaceContainer,
fBottom = &boxFaces[0]; fBottom, fTop, fFront, fBack, fLeft, fRight))
// find vertical faces
fFront = fBottom->FindAdjacentForSide( Q_BOTTOM, boxFaces );
fLeft = fBottom->FindAdjacentForSide( Q_RIGHT, boxFaces );
fBack = fBottom->FindAdjacentForSide( Q_TOP, boxFaces );
fRight = fBottom->FindAdjacentForSide( Q_LEFT, boxFaces );
// check the found
if ( !fFront || !fBack || !fLeft || !fRight )
//return error(COMPERR_BAD_SHAPE);
return false;
// top face
fTop = 0;
int i = 1;
for(; i < boxFaces.size() && !fTop; ++i ) {
fTop = & boxFaces[ i ];
if ( fTop==fFront || fTop==fLeft || fTop==fBack || fTop==fRight )
fTop = 0;
}
// set bottom of the top side
if ( !fTop->SetBottomSide( fFront->GetSide( Q_TOP ) )) {
if ( !fFront->IsComplex() )
//return error( ERR_LI("Error in StdMeshers_CompositeHexa_3D::Compute()"));
return false;
else {
_QuadFaceGrid::TChildIterator chIt = fFront->GetChildren();
while ( chIt.more() ) {
const _QuadFaceGrid& frontChild = chIt.next();
if ( fTop->SetBottomSide( frontChild.GetSide( Q_TOP )))
break;
}
}
}
if ( !fTop )
//return error(COMPERR_BAD_SHAPE);
return false; return false;
// Find a less complex side
_QuadFaceGrid * lessComplexSide = & boxFaceContainer.front();
list< _QuadFaceGrid >::iterator face = boxFaceContainer.begin();
for ( ++face; face != boxFaceContainer.end() && lessComplexSide->IsComplex(); ++face )
if ( face->NbChildren() < lessComplexSide->NbChildren() )
lessComplexSide = & *face;
TopTools_SequenceOfShape BottomFaces; // Get an 1D size of lessComplexSide
_QuadFaceGrid::TChildIterator aCI = fBottom->GetChildren(); int nbSeg1 = 0;
while( aCI.more() ) { vector<TopoDS_Edge> edges;
const _QuadFaceGrid& currChild = aCI.next(); if ( !lessComplexSide->GetHoriEdges(edges) )
BottomFaces.Append(currChild.GetFace()); return false;
for ( size_t i = 0; i < edges.size(); ++i )
{
const vector<int>& nbElems = aResMap[ theMesh.GetSubMesh( edges[i] )];
if ( !nbElems.empty() )
nbSeg1 += Max( nbElems[ SMDSEntity_Edge ], nbElems[ SMDSEntity_Quad_Edge ]);
} }
// find boundary edges and internal nodes for bottom face
TopTools_SequenceOfShape BndEdges; // Get an 1D size of a box side ortogonal to lessComplexSide
int nb0d_in = 0; int nbSeg2 = 0;
//TopTools_MapOfShape BndEdges; _QuadFaceGrid* ortoSide =
for(i=1; i<=BottomFaces.Length(); i++) { lessComplexSide->FindAdjacentForSide( Q_LEFT, boxFaceContainer, B_UNDEFINED );
for (TopExp_Explorer exp(BottomFaces.Value(i), TopAbs_EDGE); exp.More(); exp.Next()) { edges.clear();
int nb0 = 0; if ( !ortoSide || !ortoSide->GetHoriEdges(edges) ) return false;
SMESH_subMesh *sm = theMesh.GetSubMesh(exp.Current()); for ( size_t i = 0; i < edges.size(); ++i )
if( sm ) { {
MapShapeNbElemsItr anIt = aResMap.find(sm); const vector<int>& nbElems = aResMap[ theMesh.GetSubMesh( edges[i] )];
if( anIt == aResMap.end() ) continue; if ( !nbElems.empty() )
std::vector<int> aVec = (*anIt).second; nbSeg2 += Max( nbElems[ SMDSEntity_Edge ], nbElems[ SMDSEntity_Quad_Edge ]);
nb0 = aVec[SMDSEntity_Node]; }
}
int j = 1; // Get an 2D size of a box side ortogonal to lessComplexSide
for(; j<=BndEdges.Length(); j++) { int nbFaces = 0, nbQuadFace = 0;
if( BndEdges.Value(j) == exp.Current() ) { list< TopoDS_Face > sideFaces;
// internal edge => remove it if ( ortoSide->IsComplex() )
BndEdges.Remove(j); for ( _QuadFaceGrid::TChildIterator child = ortoSide->GetChildren(); child.more(); )
nb0d_in += nb0; sideFaces.push_back( child.next().GetFace() );
break; else
} sideFaces.push_back( ortoSide->GetFace() );
} //
if( j > BndEdges.Length() ) { list< TopoDS_Face >::iterator f = sideFaces.begin();
BndEdges.Append(exp.Current()); for ( ; f != sideFaces.end(); ++f )
} {
//if( BndEdges.Contains(exp.Current()) ) { const vector<int>& nbElems = aResMap[ theMesh.GetSubMesh( *f )];
//BndEdges.Remove( exp.Current() ); if ( !nbElems.empty() )
//} {
//else { nbFaces = nbElems[ SMDSEntity_Quadrangle ];
//BndEdges.Add( exp.Current() ); nbQuadFace = nbElems[ SMDSEntity_Quad_Quadrangle ];
//}
} }
} }
// find number of 1d elems for bottom face // Fill nb of elements
int nb1d = 0; vector<int> aResVec(SMDSEntity_Last,0);
for(i=1; i<=BndEdges.Length(); i++) { int nbSeg3 = ( nbFaces + nbQuadFace ) / nbSeg2;
SMESH_subMesh *sm = theMesh.GetSubMesh(BndEdges.Value(i)); aResVec[SMDSEntity_Node] = (nbSeg1-1) * (nbSeg2-1) * (nbSeg3-1);
if( sm ) { aResVec[SMDSEntity_Hexa] = nbSeg1 * nbFaces;
MapShapeNbElemsItr anIt = aResMap.find(sm); aResVec[SMDSEntity_Quad_Hexa] = nbSeg1 * nbQuadFace;
if( anIt == aResMap.end() ) continue;
std::vector<int> aVec = (*anIt).second;
nb1d += Max(aVec[SMDSEntity_Edge],aVec[SMDSEntity_Quad_Edge]);
}
}
// find number of 2d elems on side faces aResMap.insert( make_pair( theMesh.GetSubMesh(theShape), aResVec ));
int nb2d = 0;
nb2d += GetNb2d(fFront, theMesh, aResMap);
nb2d += GetNb2d(fRight, theMesh, aResMap);
nb2d += GetNb2d(fBack, theMesh, aResMap);
nb2d += GetNb2d(fLeft, theMesh, aResMap);
// find number of 2d elems and nodes on bottom faces
int nb0d=0, nb2d_3=0, nb2d_4=0;
for(i=1; i<=BottomFaces.Length(); i++) {
SMESH_subMesh *sm = theMesh.GetSubMesh(BottomFaces.Value(i));
if( sm ) {
MapShapeNbElemsItr anIt = aResMap.find(sm);
if( anIt == aResMap.end() ) continue;
std::vector<int> aVec = (*anIt).second;
nb0d += aVec[SMDSEntity_Node];
nb2d_3 += Max(aVec[SMDSEntity_Triangle], aVec[SMDSEntity_Quad_Triangle]);
nb2d_4 += Max(aVec[SMDSEntity_Quadrangle], aVec[SMDSEntity_Quad_Quadrangle]);
}
}
nb0d += nb0d_in;
std::vector<int> aResVec(SMDSEntity_Last);
for(int i=SMDSEntity_Node; i<SMDSEntity_Last; i++) aResVec[i] = 0;
if(_quadraticMesh) {
aResVec[SMDSEntity_Quad_Penta] = nb2d_3 * ( nb2d/nb1d );
aResVec[SMDSEntity_Quad_Hexa] = nb2d_4 * ( nb2d/nb1d );
aResVec[SMDSEntity_Node] = nb0d * ( 2*nb2d/nb1d - 1 );
}
else {
aResVec[SMDSEntity_Node] = nb0d * ( nb2d/nb1d - 1 );
aResVec[SMDSEntity_Penta] = nb2d_3 * ( nb2d/nb1d );
aResVec[SMDSEntity_Hexa] = nb2d_4 * ( nb2d/nb1d );
}
SMESH_subMesh * sm = theMesh.GetSubMesh(theShape);
aResMap.insert(std::make_pair(sm,aResVec));
return true; return true;
} }
@ -795,7 +706,8 @@ bool _QuadFaceGrid::Init(const TopoDS_Face& f)
bool _QuadFaceGrid::AddContinuousFace( const _QuadFaceGrid& other ) bool _QuadFaceGrid::AddContinuousFace( const _QuadFaceGrid& other )
{ {
for ( int i = 0; i < 4; ++i ) { for ( int i = 0; i < 4; ++i )
{
const _FaceSide& otherSide = other.GetSide( i ); const _FaceSide& otherSide = other.GetSide( i );
int iMyCommon; int iMyCommon;
if ( mySides.Contain( otherSide, &iMyCommon ) ) { if ( mySides.Contain( otherSide, &iMyCommon ) ) {
@ -824,14 +736,28 @@ bool _QuadFaceGrid::AddContinuousFace( const _QuadFaceGrid& other )
myChildren.push_back( *this ); myChildren.push_back( *this );
myFace.Nullify(); myFace.Nullify();
} }
myChildren.push_back( other ); if ( other.IsComplex() )
int otherBottomIndex = ( 4 + i - iMyCommon + 2 ) % 4; for ( TChildIterator children = other.GetChildren(); children.more(); )
myChildren.back().SetBottomSide( other.GetSide( otherBottomIndex )); myChildren.push_back( children.next() );
else
myChildren.push_back( other );
myLeftBottomChild = 0;
//int otherBottomIndex = ( 4 + i - iMyCommon + 2 ) % 4;
//myChildren.back().SetBottomSide( other.GetSide( otherBottomIndex ));
// collect vertices in mySides // collect vertices in mySides
mySides.AppendSide( other.GetSide(0) ); if ( other.IsComplex() )
mySides.AppendSide( other.GetSide(1) ); for ( TChildIterator children = other.GetChildren(); children.more(); )
mySides.AppendSide( other.GetSide(2) ); {
mySides.AppendSide( other.GetSide(3) ); const _QuadFaceGrid& child = children.next();
for ( int i = 0; i < 4; ++i )
mySides.AppendSide( child.GetSide(i) );
}
else
for ( int i = 0; i < 4; ++i )
mySides.AppendSide( other.GetSide(i) );
return true; return true;
} }
} }
@ -886,12 +812,17 @@ bool _QuadFaceGrid::SetBottomSide(const _FaceSide& bottom, int* sideIndex)
*/ */
//================================================================================ //================================================================================
_QuadFaceGrid* _QuadFaceGrid::FindAdjacentForSide(int i, vector<_QuadFaceGrid>& faces) const _QuadFaceGrid* _QuadFaceGrid::FindAdjacentForSide(int i,
list<_QuadFaceGrid>& faces,
EBoxSides id) const
{ {
for ( int iF = 0; iF < faces.size(); ++iF ) { const _FaceSide & iSide = GetSide( i );
_QuadFaceGrid* f = &faces[ iF ]; list< _QuadFaceGrid >::iterator boxFace = faces.begin();
if ( f != this && f->SetBottomSide( GetSide( i ))) for ( ; boxFace != faces.end(); ++boxFace )
return f; {
_QuadFaceGrid* f = & (*boxFace);
if ( f != this && f->SetBottomSide( iSide ))
return f->SetID( id ), f;
} }
return (_QuadFaceGrid*) 0; return (_QuadFaceGrid*) 0;
} }
@ -1284,6 +1215,35 @@ int _QuadFaceGrid::GetNbVertSegments(SMESH_Mesh& mesh, bool withBrothers) const
return nbSegs; return nbSegs;
} }
//================================================================================
/*!
* \brief Return edge on the hirizontal bottom sides
*/
//================================================================================
int _QuadFaceGrid::GetHoriEdges(vector<TopoDS_Edge> & edges) const
{
if ( myLeftBottomChild )
{
return myLeftBottomChild->GetHoriEdges( edges );
}
else
{
const _FaceSide* bottom = mySides.GetSide( Q_BOTTOM );
int i = 0;
while ( true ) {
TopoDS_Edge e = bottom->Edge( i++ );
if ( e.IsNull() )
break;
else
edges.push_back( e );
}
if ( myRightBrother )
myRightBrother->GetHoriEdges( edges );
}
return edges.size();
}
//================================================================================ //================================================================================
/*! /*!
* \brief Return a node by its position * \brief Return a node by its position
@ -1498,7 +1458,6 @@ int _FaceSide::NbVertices() const
{ {
if ( myChildren.empty() ) if ( myChildren.empty() )
return myVertices.Extent(); return myVertices.Extent();
// return myVertices.size();
return myNbChildren + 1; return myNbChildren + 1;
} }
@ -1545,6 +1504,23 @@ TopoDS_Vertex _FaceSide::Vertex(int i) const
return GetSide(i)->FirstVertex(); return GetSide(i)->FirstVertex();
} }
//================================================================================
/*!
* \brief Return i-the zero-based edge of the side
*/
//================================================================================
TopoDS_Edge _FaceSide::Edge(int i) const
{
if ( i == 0 && !myEdge.IsNull() )
return myEdge;
if ( const _FaceSide* iSide = GetSide( i ))
return iSide->myEdge;
return TopoDS_Edge();
}
//======================================================================= //=======================================================================
//function : Contain //function : Contain
//purpose : //purpose :
@ -1557,9 +1533,6 @@ bool _FaceSide::Contain( const _FaceSide& side, int* which ) const
if ( which ) if ( which )
*which = 0; *which = 0;
int nbCommon = 0; int nbCommon = 0;
// set<const TopoDS_TShape*>::iterator v, vEnd = side.myVertices.end();
// for ( v = side.myVertices.begin(); v != vEnd; ++v )
// nbCommon += ( myVertices.find( *v ) != myVertices.end() );
TopTools_MapIteratorOfMapOfShape vIt ( side.myVertices ); TopTools_MapIteratorOfMapOfShape vIt ( side.myVertices );
for ( ; vIt.More(); vIt.Next() ) for ( ; vIt.More(); vIt.Next() )
nbCommon += ( myVertices.Contains( vIt.Key() )); nbCommon += ( myVertices.Contains( vIt.Key() ));
@ -1583,7 +1556,6 @@ bool _FaceSide::Contain( const _FaceSide& side, int* which ) const
bool _FaceSide::Contain( const TopoDS_Vertex& vertex ) const bool _FaceSide::Contain( const TopoDS_Vertex& vertex ) const
{ {
return myVertices.Contains( vertex ); return myVertices.Contains( vertex );
// return myVertices.find( ptr( vertex )) != myVertices.end();
} }
//======================================================================= //=======================================================================
@ -1601,7 +1573,6 @@ void _FaceSide::AppendSide( const _FaceSide& side )
} }
myChildren.push_back( side ); myChildren.push_back( side );
myNbChildren++; myNbChildren++;
//myVertices.insert( side.myVertices.begin(), side.myVertices.end() );
TopTools_MapIteratorOfMapOfShape vIt ( side.myVertices ); TopTools_MapIteratorOfMapOfShape vIt ( side.myVertices );
for ( ; vIt.More(); vIt.Next() ) for ( ; vIt.More(); vIt.Next() )
myVertices.Add( vIt.Key() ); myVertices.Add( vIt.Key() );

View File

@ -31,6 +31,7 @@ class SMESH_Mesh;
class StdMeshers_FaceSide; class StdMeshers_FaceSide;
class TopoDS_Edge; class TopoDS_Edge;
class TopoDS_Face; class TopoDS_Face;
struct _QuadFaceGrid;
/*! /*!
* \brief Computes hexahedral mesh on a box with composite sides * \brief Computes hexahedral mesh on a box with composite sides
@ -55,7 +56,15 @@ public:
Hypothesis_Status& aStatus); Hypothesis_Status& aStatus);
private: private:
// private fields
bool findBoxFaces( const TopoDS_Shape& shape,
list< _QuadFaceGrid >& boxFaceContainer,
_QuadFaceGrid * & fBottom,
_QuadFaceGrid * & fTop,
_QuadFaceGrid * & fFront,
_QuadFaceGrid * & fBack,
_QuadFaceGrid * & fLeft,
_QuadFaceGrid * & fRight);
}; };
#endif #endif