-// Copyright (C) 2007-2020 CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2021 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
bool _hasInternalFaces;
public:
virtual ~Solid() {}
- virtual bool Contains( TGeomID subID ) const { return true; }
- virtual bool ContainsAny( const vector< TGeomID>& subIDs ) const { return true; }
+ virtual bool Contains( TGeomID /*subID*/ ) const { return true; }
+ virtual bool ContainsAny( const vector< TGeomID>& /*subIDs*/ ) const { return true; }
virtual TopAbs_Orientation Orientation( const TopoDS_Shape& s ) const { return s.Orientation(); }
- virtual bool IsOutsideOriented( TGeomID faceID ) const { return true; }
+ virtual bool IsOutsideOriented( TGeomID /*faceID*/ ) const { return true; }
void SetID( TGeomID id ) { _id = id; }
TGeomID ID() const { return _id; }
void SetHasInternalFaces( bool has ) { _hasInternalFaces = has; }
{
struct _Split // data of a link split
{
- int _linkID; // hex link ID
+ int _linkID; // hex link ID
_Node* _nodes[2];
int _iCheckIteration; // iteration where split is tried as Hexahedron split
_Link* _checkedSplit; // split set to hex links
- bool _isUsed; // used in a volume
+ bool _isUsed; // used in a volume
_Split( _Link & split, int iLink ):
_linkID( iLink ), _nodes{ split._nodes[0], split._nodes[1] },
};
vector< _nodeDef > _nodes;
- vector< int > _quantities;
+ vector< int > _quantities;
_volumeDef* _next; // to store several _volumeDefs in a chain
TGeomID _solidID;
const SMDS_MeshElement* _volume; // new volume
void getBoundaryElems( vector< const SMDS_MeshElement* > & boundaryVolumes );
void removeExcessSideDivision(const vector< Hexahedron* >& allHexa);
void removeExcessNodes(vector< Hexahedron* >& allHexa);
+ void preventVolumesOverlapping();
TGeomID getAnyFace() const;
void cutByExtendedInternal( std::vector< Hexahedron* >& hexes,
const TColStd_MapOfInteger& intEdgeIDs );
}
#ifdef _DEBUG_
_cellID = cellID;
+#else
+ (void)cellID; // unused in release mode
#endif
}
{
_i = i; _j = j; _k = k;
+ bool isCompute = solid;
if ( !solid )
solid = _grid->GetSolid();
_intNodes.clear();
_vIntNodes.clear();
+ if ( !isCompute )
+ return;
+
if ( _nbFaceIntNodes + _eIntPoints.size() > 0 &&
_nbFaceIntNodes + _eIntPoints.size() + _nbCornerNodes > 3)
{
case 3: // at a corner
{
_Node& node = _hexNodes[ subEntity - SMESH_Block::ID_FirstV ];
- if ( node.Node() > 0 )
+ if ( node.Node() )
{
if ( node._intPoint )
node._intPoint->Add( _eIntPoints[ iP ]->_faceIDs, _eIntPoints[ iP ]->_node );
} // loop on _eIntPoints
}
- else if ( 3 < _nbCornerNodes && _nbCornerNodes < 8 ) // _nbFaceIntNodes == 0
+ else if (( 3 < _nbCornerNodes && _nbCornerNodes < 8 ) || // _nbFaceIntNodes == 0
+ ( !_grid->_geometry.IsOneSolid() ))
{
_Link split;
// create sub-links (_splits) of whole links
for ( int iN = 0; iN < 8; ++iN )
_hexNodes[iN]._usedInFace = 0;
+ if ( intFlag & IS_CUT_BY_INTERNAL_FACE && !_grid->_toAddEdges ) // Issue #19913
+ preventVolumesOverlapping();
+
// Create polygons from quadrangles
// --------------------------------
vector<_Node*> chainNodes;
_Face* coplanarPolyg;
- bool hasEdgeIntersections = !_eIntPoints.empty();
+ const bool hasEdgeIntersections = !_eIntPoints.empty();
+ const bool toCheckSideDivision = isImplementEdges() || intFlag & IS_CUT_BY_INTERNAL_FACE;
for ( int iF = 0; iF < 6; ++iF ) // loop on 6 sides of a hexahedron
{
n1 = split.FirstNode();
if ( n1 == n2 &&
n1->_intPoint &&
- (( n1->_intPoint->_faceIDs.size() > 1 && isImplementEdges() ) ||
+ (( n1->_intPoint->_faceIDs.size() > 1 && toCheckSideDivision ) ||
( n1->_isInternalFlags )))
{
// n1 is at intersection with EDGE
if ( hex ) // split hexahedron
{
intHexa.push_back( hex );
- if ( hex->_nbFaceIntNodes > 0 || hex->_eIntPoints.size() > 0 )
+ if ( hex->_nbFaceIntNodes > 0 ||
+ hex->_eIntPoints.size() > 0 ||
+ hex->getSolids( solidIDs ) > 1 )
continue; // treat intersected hex later in parallel
this->init( hex->_i, hex->_j, hex->_k );
}
continue;
// perform intersection
- E_IntersectPoint* eip, *vip;
+ E_IntersectPoint* eip, *vip = 0;
for ( int iDirZ = 0; iDirZ < 3; ++iDirZ )
{
GridPlanes& planes = pln[ iDirZ ];
{
curIntPnt._paramOnLine = coords[ ijk[ iDir ]] - coords[0] + _grid->_tol;
const GridLine& line = _grid->_lines[ iDir ][ lineIndex[ iL ]];
- multiset< F_IntersectPoint >::const_iterator ip =
- line._intPoints.upper_bound( curIntPnt );
- --ip;
- firstIntPnt = &(*ip);
+ if ( !line._intPoints.empty() )
+ {
+ multiset< F_IntersectPoint >::const_iterator ip =
+ line._intPoints.upper_bound( curIntPnt );
+ --ip;
+ firstIntPnt = &(*ip);
+ }
}
else if ( !link._fIntPoints.empty() )
{
cout << "BUG: not shared link. IKJ = ( "<< _i << " " << _j << " " << _k << " )" << endl
<< "n1 (" << p1.X() << ", "<< p1.Y() << ", "<< p1.Z() << " )" << endl
<< "n2 (" << p2.X() << ", "<< p2.Y() << ", "<< p2.Z() << " )" << endl;
+#else
+ (void)link; // unused in release mode
#endif
return false;
}
if ( loopsJoined )
{
// set unchanged polygons
- std::vector< int > newQuantities;
+ std::vector< int > newQuantities;
std::vector< _volumeDef::_nodeDef > newNodes;
vector< SMESH_Block::TShapeID > newNames;
newQuantities.reserve( volDef->_quantities.size() );
if ( allQuads )
{
// set side nodes as this: bottom, top, top, ...
- int iTop, iBot; // side indices
+ int iTop = 0, iBot = 0; // side indices
for ( int iS = 0; iS < 6; ++iS )
{
if ( vol->_names[ iS ] == SMESH_Block::ID_Fxy0 )
} // removeExcessNodes()
+ //================================================================================
+ /*!
+ * \brief [Issue #19913] Modify _hexLinks._splits to prevent creating overlapping volumes
+ */
+ //================================================================================
+
+ void Hexahedron::preventVolumesOverlapping()
+ {
+ // Cut off a quadrangle corner if two links sharing the corner
+ // are shared by same two solids, in this case each of solids gets
+ // a triangle for it-self.
+ std::vector< TGeomID > soIDs[4];
+ for ( int iF = 0; iF < 6; ++iF ) // loop on 6 sides of a hexahedron
+ {
+ _Face& quad = _hexQuads[ iF ] ;
+
+ int iFOpposite = iF + ( iF % 2 ? -1 : 1 );
+ _Face& quadOpp = _hexQuads[ iFOpposite ] ;
+
+ int nbSides = 0, nbSidesOpp = 0;
+ for ( int iE = 0; iE < 4; ++iE ) // loop on 4 sides of a quadrangle
+ {
+ nbSides += ( quad._links [ iE ].NbResultLinks() > 0 );
+ nbSidesOpp += ( quadOpp._links[ iE ].NbResultLinks() > 0 );
+ }
+ if ( nbSides < 4 || nbSidesOpp != 2 )
+ continue;
+
+ for ( int iE = 0; iE < 4; ++iE )
+ {
+ soIDs[ iE ].clear();
+ _Node* n = quad._links[ iE ].FirstNode();
+ if ( n->_intPoint && n->_intPoint->_faceIDs.size() )
+ soIDs[ iE ] = _grid->GetSolidIDs( n->_intPoint->_faceIDs[0] );
+ }
+ if ((( soIDs[0].size() >= 2 ) +
+ ( soIDs[1].size() >= 2 ) +
+ ( soIDs[2].size() >= 2 ) +
+ ( soIDs[3].size() >= 2 ) ) < 3 )
+ continue;
+
+ bool done = false;
+ for ( int i = 0; i < 4; ++i )
+ {
+ int i1 = _grid->_helper->WrapIndex( i + 1, 4 );
+ int i2 = _grid->_helper->WrapIndex( i + 2, 4 );
+ int i3 = _grid->_helper->WrapIndex( i + 3, 4 );
+ if ( soIDs[i1].size() == 2 && soIDs[i ] != soIDs[i1] &&
+ soIDs[i2].size() == 2 && soIDs[i1] == soIDs[i2] &&
+ soIDs[i3].size() == 2 && soIDs[i2] == soIDs[i3] )
+ {
+ quad._links[ i1 ]._link->_splits.clear();
+ quad._links[ i2 ]._link->_splits.clear();
+ done = true;
+ break;
+ }
+ }
+ if ( done )
+ break;
+ }
+ return;
+ } // preventVolumesOverlapping()
+
//================================================================================
/*!
* \brief Set to _hexLinks a next portion of splits located on one side of INTERNAL FACEs
*/
//=============================================================================
-bool StdMeshers_Cartesian_3D::Evaluate(SMESH_Mesh & theMesh,
- const TopoDS_Shape & theShape,
- MapShapeNbElems& theResMap)
+bool StdMeshers_Cartesian_3D::Evaluate(SMESH_Mesh & /*theMesh*/,
+ const TopoDS_Shape & /*theShape*/,
+ MapShapeNbElems& /*theResMap*/)
{
// TODO
// std::vector<int> aResVec(SMDSEntity_Last);
// --------------------------------------------------------------------------------
// unsetting _alwaysComputed flag if "Cartesian_3D" was removed
//
- virtual void ProcessEvent(const int event,
+ virtual void ProcessEvent(const int /*event*/,
const int eventType,
SMESH_subMesh* subMeshOfSolid,
- SMESH_subMeshEventListenerData* data,
- const SMESH_Hypothesis* hyp = 0)
+ SMESH_subMeshEventListenerData* /*data*/,
+ const SMESH_Hypothesis* /*hyp*/ = 0)
{
if ( eventType == SMESH_subMesh::COMPUTE_EVENT )
{