Version: 9.16.0
StdMeshers_Cartesian_3D_Hexahedron.hxx
Go to the documentation of this file.
1// Copyright (C) 2016-2026 CEA, EDF
2//
3// This library is free software; you can redistribute it and/or
4// modify it under the terms of the GNU Lesser General Public
5// License as published by the Free Software Foundation; either
6// version 2.1 of the License, or (at your option) any later version.
7//
8// This library is distributed in the hope that it will be useful,
9// but WITHOUT ANY WARRANTY; without even the implied warranty of
10// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11// Lesser General Public License for more details.
12//
13// You should have received a copy of the GNU Lesser General Public
14// License along with this library; if not, write to the Free Software
15// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16//
17// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
18//
19// File : StdMeshers_Cartesian_3D_Hexahedron.hxx
20// Module : SMESH
21// Purpose: Make BodyFitting mesh algorithm more modular and testable
22//
23
24#ifndef _SMESH_Cartesian_3D_HEXAHEDRON_HXX_
25#define _SMESH_Cartesian_3D_HEXAHEDRON_HXX_
26
27// BOOST
28#include <boost/container/flat_map.hpp>
29
30// STD
31#include <utilities.h>
32#include <vector>
33
34// SMESH
35#include "SMESH_StdMeshers.hxx"
37
38namespace StdMeshers
39{
40namespace Cartesian3D
41{
42 // --------------------------------------------------------------------------
47 {
48 int _iDir;
49 int _dInd[4][3];
50 size_t _nbCells[3];
51 int _i,_j,_k;
53
55 _iDir( iDir ),
56 _dInd{ {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0} },
57 _nbCells{ grid->_coords[0].size() - 1,
58 grid->_coords[1].size() - 1,
59 grid->_coords[2].size() - 1 },
60 _grid( grid )
61 {
62 const int iDirOther[3][2] = {{ 1,2 },{ 0,2 },{ 0,1 }};
63 _dInd[1][ iDirOther[iDir][0] ] = -1;
64 _dInd[2][ iDirOther[iDir][1] ] = -1;
65 _dInd[3][ iDirOther[iDir][0] ] = -1; _dInd[3][ iDirOther[iDir][1] ] = -1;
66 }
67 void Init( int i, int j, int k, int link12 = 0 )
68 {
69 int iL = link12 % 4;
70 _i = i - _dInd[iL][0];
71 _j = j - _dInd[iL][1];
72 _k = k - _dInd[iL][2];
73 }
74 bool GetCell( int iL, int& i, int& j, int& k, int& cellIndex, int& linkIndex )
75 {
76 i = _i + _dInd[iL][0];
77 j = _j + _dInd[iL][1];
78 k = _k + _dInd[iL][2];
79 if ( i < 0 || i >= (int)_nbCells[0] ||
80 j < 0 || j >= (int)_nbCells[1] ||
81 k < 0 || k >= (int)_nbCells[2] )
82 return false;
83 cellIndex = _grid->CellIndex( i,j,k );
84 linkIndex = iL + _iDir * 4;
85 return true;
86 }
87 };
88
89 // --------------------------------------------------------------------------
95 {
96 // --------------------------------------------------------------------------------
97 struct _Face;
98 struct _Link;
99 enum IsInternalFlag { IS_NOT_INTERNAL, IS_INTERNAL, IS_CUT_BY_INTERNAL_FACE };
100 // --------------------------------------------------------------------------------
101 struct _Node
102 {
103 const SMDS_MeshNode* _node; // mesh node at hexahedron corner
104 const SMDS_MeshNode* _boundaryCornerNode; // missing mesh node due to hex truncation on the boundary
108
110 :_node(n), _boundaryCornerNode(0), _intPoint(ip), _usedInFace(0), _isInternalFlags(0) {}
111 const SMDS_MeshNode* Node() const
112 { return ( _intPoint && _intPoint->_node ) ? _intPoint->_node : _node; }
114 { return _node ? _node : _boundaryCornerNode; }
116 { return static_cast< const StdMeshers::Cartesian3D::E_IntersectPoint* >( _intPoint ); }
118 { return static_cast< const StdMeshers::Cartesian3D::F_IntersectPoint* >( _intPoint ); }
119 const std::vector< StdMeshers::Cartesian3D::TGeomID >& faces() const { return _intPoint->_faceIDs; }
120 StdMeshers::Cartesian3D::TGeomID face(size_t i) const { return _intPoint->_faceIDs[ i ]; }
121 void SetInternal( IsInternalFlag intFlag ) { _isInternalFlags |= intFlag; }
122 bool IsCutByInternal() const { return _isInternalFlags & IS_CUT_BY_INTERNAL_FACE; }
123 bool IsUsedInFace( const _Face* polygon = 0 )
124 {
125 return polygon ? ( _usedInFace == polygon ) : bool( _usedInFace );
126 }
128 StdMeshers::Cartesian3D::TGeomID avoidFace=-1 ) const // returns id of a common face
129 {
130 return _intPoint ? _intPoint->HasCommonFace( other, avoidFace ) : 0;
131 }
132 bool IsOnFace( StdMeshers::Cartesian3D::TGeomID faceID ) const // returns true if faceID is found
133 {
134 return _intPoint ? _intPoint->IsOnFace( faceID ) : false;
135 }
138 {
139 return _intPoint && other ? _intPoint->GetCommonFaces( other, common ) : 0;
140 }
141 gp_Pnt Point() const
142 {
143 if ( const SMDS_MeshNode* n = Node() )
144 return SMESH_NodeXYZ( n );
146 dynamic_cast< const StdMeshers::Cartesian3D::E_IntersectPoint* >( _intPoint ))
147 return eip->_point;
148 return gp_Pnt( 1e100, 0, 0 );
149 }
151 {
153 dynamic_cast< const StdMeshers::Cartesian3D::E_IntersectPoint* >( _intPoint ))
154 return eip->_shapeID;
155 return 0;
156 }
157
159 void clear();
160
161 friend std::ostream& operator<<(std::ostream& os, const _Node& node)
162 {
163 if (node._node)
164 {
165 os << "Node at hexahedron corner: ";
166 node._node->Print(os);
167 }
168 else if (node._intPoint && node._intPoint->_node)
169 {
170 os << "Node at intersection point: ";
171 node._intPoint->_node->Print(os); // intersection point
172 }
173 else
174 os << "mesh node is null\n";
175
176 return os;
177 }
178 };
179
180 // --------------------------------------------------------------------------------
181 struct _Link // link connecting two _Node's
182 {
183 static const std::size_t nodesNum = 2;
184
185 _Node* _nodes[nodesNum];
186 _Face* _faces[nodesNum]; // polygons sharing a link
187 std::vector< const StdMeshers::Cartesian3D::F_IntersectPoint* > _fIntPoints; // GridLine intersections with FACEs
188 std::vector< _Node* > _fIntNodes; // _Node's at _fIntPoints
189 std::vector< _Link > _splits;
190 _Link(): _nodes{ 0, 0 }, _faces{ 0, 0 } {}
191
192 void clear();
193
194 friend std::ostream& operator<<(std::ostream& os, const _Link& link)
195 {
196 os << "Link:\n";
197
198 for (std::size_t i = 0; i < nodesNum; ++i)
199 {
200 if (link._nodes[i])
201 os << *link._nodes[i];
202 else
203 os << "link node with index " << i << " is null\n";
204 }
205
206 os << "_fIntPoints: " << link._fIntPoints.size() << '\n';
207 os << "_fIntNodes: " << link._fIntNodes.size() << '\n';
208 os << "_splits: " << link._splits.size() << '\n';
209
210 return os;
211 }
212 };
213
214 // --------------------------------------------------------------------------------
216 {
219 _OrientedLink( _Link* link=0, bool reverse=false ): _link(link), _reverse(reverse) {}
220 void Reverse() { _reverse = !_reverse; }
221 size_t NbResultLinks() const { return _link->_splits.size(); }
223 {
224 return _OrientedLink(&_link->_splits[_reverse ? NbResultLinks()-i-1 : i],_reverse);
225 }
226 _Node* FirstNode() const { return _link->_nodes[ _reverse ]; }
227 _Node* LastNode() const { return _link->_nodes[ !_reverse ]; }
228 operator bool() const { return _link; }
229
230 // returns supporting FACEs
231 std::vector< StdMeshers::Cartesian3D::TGeomID > GetNotUsedFaces
232 (const std::set<StdMeshers::Cartesian3D::TGeomID>& usedIDs ) const
233 {
234 std::vector< StdMeshers::Cartesian3D::TGeomID > faces;
236 if (( ip0 = _link->_nodes[0]->_intPoint ) &&
237 ( ip1 = _link->_nodes[1]->_intPoint ))
238 {
239 for ( size_t i = 0; i < ip0->_faceIDs.size(); ++i )
240 if ( ip1->IsOnFace ( ip0->_faceIDs[i] ) &&
241 !usedIDs.count( ip0->_faceIDs[i] ) )
242 faces.push_back( ip0->_faceIDs[i] );
243 }
244 return faces;
245 }
246
247 bool HasEdgeNodes() const
248 {
249 return ( dynamic_cast< const StdMeshers::Cartesian3D::E_IntersectPoint* >( _link->_nodes[0]->_intPoint ) ||
250 dynamic_cast< const StdMeshers::Cartesian3D::E_IntersectPoint* >( _link->_nodes[1]->_intPoint ));
251 }
252 int NbFaces() const
253 {
254 return !_link->_faces[0] ? 0 : 1 + bool( _link->_faces[1] );
255 }
256 void AddFace( _Face* f )
257 {
258 if ( _link->_faces[0] ) {
259 _link->_faces[1] = f;
260 }
261 else {
262 _link->_faces[0] = f;
263 _link->_faces[1] = 0;
264 }
265 }
266 void RemoveFace( const _Face* f )
267 {
268 if ( !_link->_faces[0] ) return;
269
270 if ( _link->_faces[1] == f ) {
271 _link->_faces[1] = 0;
272 }
273 else if ( _link->_faces[0] == f ) {
274 _link->_faces[0] = 0;
275 if ( _link->_faces[1] ) {
276 _link->_faces[0] = _link->_faces[1];
277 _link->_faces[1] = 0;
278 }
279 }
280 }
281
282 friend std::ostream& operator<<(std::ostream& os, const _OrientedLink& link)
283 {
284 if (link._link)
285 os << "Oriented " << *link._link;
286 else
287 os << "Oriented link is null\n";
288
289 return os;
290 }
291 };
292
293 // --------------------------------------------------------------------------------
295 {
296 struct _Split // data of a link split
297 {
298 int _linkID; // hex link ID
299 _Node* _nodes[2];
300 int _iCheckIteration; // iteration where split is tried as Hexahedron split
301 _Link* _checkedSplit; // split set to hex links
302 bool _isUsed; // used in a volume
303
304 _Split( _Link & split, int iLink ):
305 _linkID( iLink ), _nodes{ split._nodes[0], split._nodes[1] },
306 _iCheckIteration( 0 ), _isUsed( false )
307 {}
308 bool IsCheckedOrUsed( bool used ) const { return used ? _isUsed : _iCheckIteration > 0; }
309 };
311 std::vector< _Split > _splits;
314 size_t _nbUsed;
315 std::vector< _Node* > _freeNodes; // nodes reached while composing a split set
316
317 _SplitIterator( _Link* hexLinks ):
318 _hexLinks( hexLinks ), _iterationNb(0), _nbChecked(0), _nbUsed(0)
319 {
320 _freeNodes.reserve( 12 );
321 _splits.reserve( 24 );
322 for ( int iL = 0; iL < 12; ++iL )
323 for ( size_t iS = 0; iS < _hexLinks[ iL ]._splits.size(); ++iS )
324 _splits.emplace_back( _hexLinks[ iL ]._splits[ iS ], iL );
325 Next();
326 }
327 bool More() const { return _nbUsed < _splits.size(); }
328 bool Next();
329 };
330
331 // --------------------------------------------------------------------------------
332 struct _Face
333 {
335 std::vector< _OrientedLink > _links; // links on GridLine's
336 std::vector< _Link > _polyLinks; // links added to close a polygonal face
337 std::vector< _Node* > _eIntNodes; // nodes at intersection with EDGEs
338
339 _Face():_name( SMESH_Block::ID_NONE )
340 {}
341 bool IsPolyLink( const _OrientedLink& ol )
342 {
343 return _polyLinks.empty() ? false :
344 ( &_polyLinks[0] <= ol._link && ol._link <= &_polyLinks.back() );
345 }
346 void AddPolyLink(_Node* n0, _Node* n1, _Face* faceToFindEqual=0)
347 {
348 if ( faceToFindEqual && faceToFindEqual != this ) {
349 for ( size_t iL = 0; iL < faceToFindEqual->_polyLinks.size(); ++iL )
350 if ( faceToFindEqual->_polyLinks[iL]._nodes[0] == n1 &&
351 faceToFindEqual->_polyLinks[iL]._nodes[1] == n0 )
352 {
353 _links.push_back
354 ( _OrientedLink( & faceToFindEqual->_polyLinks[iL], /*reverse=*/true ));
355 return;
356 }
357 }
358 _Link l;
359 l._nodes[0] = n0;
360 l._nodes[1] = n1;
361 _polyLinks.push_back( l );
362 _links.push_back( _OrientedLink( &_polyLinks.back() ));
363 }
364
365 friend std::ostream& operator<<(std::ostream& os, const _Face& face)
366 {
367 os << "Face " << face._name << '\n';
368
369 os << "Links on GridLines: \n";
370 for (const auto& link : face._links)
371 {
372 os << link;
373 }
374
375 os << "Links added to close a polygonal face: \n";
376 for (const auto& link : face._polyLinks)
377 {
378 os << link;
379 }
380
381 os << "Nodes at intersection with EDGEs: \n";
382 for (const auto node : face._eIntNodes)
383 {
384 if (node)
385 {
386 os << *node;
387 }
388 }
389
390 return os;
391 }
392 };
393
394 // --------------------------------------------------------------------------------
395 struct _volumeDef // holder of nodes of a volume mesh element
396 {
397 typedef void* _ptr;
398
399 struct _nodeDef
400 {
401 const SMDS_MeshNode* _node; // mesh node at hexahedron corner
403
404 _nodeDef(): _node(0), _intPoint(0) {}
405 _nodeDef( _Node* n ): _node( n->_node), _intPoint( n->_intPoint ) {}
406 const SMDS_MeshNode* Node() const
407 { return ( _intPoint && _intPoint->_node ) ? _intPoint->_node : _node; }
409 { return static_cast< const StdMeshers::Cartesian3D::E_IntersectPoint* >( _intPoint ); }
410 _ptr Ptr() const { return Node() ? (_ptr) Node() : (_ptr) EdgeIntPnt(); }
411 bool operator==(const _nodeDef& other ) const { return Ptr() == other.Ptr(); }
412
413 friend std::ostream& operator<<(std::ostream& os, const _nodeDef& node)
414 {
415 if (node._node)
416 {
417 os << "Node at hexahedron corner: ";
418 node._node->Print(os);
419 }
420 else if (node._intPoint && node._intPoint->_node)
421 {
422 os << "Node at intersection point: ";
423 node._intPoint->_node->Print(os); // intersection point
424 }
425 else
426 os << "mesh node is null\n";
427
428 return os;
429 }
430 };
431
432 std::vector< _nodeDef > _nodes;
433 std::vector< int > _quantities;
434 _volumeDef* _next; // to store several _volumeDefs in a chain
436 double _size;
437 const SMDS_MeshElement* _volume; // new volume
438 std::vector<const SMDS_MeshElement*> _brotherVolume; // produced due to poly split
439 std::vector< SMESH_Block::TShapeID > _names; // name of side a polygon originates from
440
441 _volumeDef(): _next(0), _solidID(0), _size(0), _volume(0) {}
442 ~_volumeDef() { delete _next; }
444 _next(0), _solidID( other._solidID ), _size( other._size ), _volume( other._volume )
445 { _nodes.swap( other._nodes ); _quantities.swap( other._quantities ); other._volume = 0;
446 _names.swap( other._names ); }
447
448 size_t size() const { return 1 + ( _next ? _next->size() : 0 ); } // nb _volumeDef in a chain
449 _volumeDef* at(int index)
450 { return index == 0 ? this : ( _next ? _next->at(index-1) : _next ); }
451
452 void Set( _Node** nodes, int nb )
453 { _nodes.assign( nodes, nodes + nb ); }
454
455 void SetNext( _volumeDef* vd )
456 { if ( _next ) { _next->SetNext( vd ); } else { _next = vd; }}
457
458 bool IsEmpty() const { return (( _nodes.empty() ) &&
459 ( !_next || _next->IsEmpty() )); }
460 bool IsPolyhedron() const { return ( !_quantities.empty() ||
461 ( _next && !_next->_quantities.empty() )); }
462
463 std::vector<std::set<std::pair<int, int>>> getPolygonsEdges() const;
464 std::vector<std::set<std::pair<int, int>>> findOpenEdges() const;
465 int getStartNodeIndex(const int polygon) const;
466 std::map<int, std::vector<int>> findOverlappingPolygons() const;
467 bool divideOverlappingPolygons();
468 bool fixOpenEdgesPolygons();
469 bool capOpenEdgesPolygons(const std::vector<std::set<std::pair<int, int>>>& edgesByPolygon);
470 bool removeOpenEdgesPolygons(const std::vector<std::set<std::pair<int, int>>>& edgesByPolygon);
471
472 struct _linkDef: public std::pair<_ptr,_ptr> // to join polygons in removeExcessSideDivision()
473 {
474 _nodeDef _node1;//, _node2;
475 mutable /*const */_linkDef *_prev, *_next;
477
478 _linkDef():_prev(0), _next(0) {}
479
480 void init( const _nodeDef& n1, const _nodeDef& n2, size_t iLoop )
481 {
482 _node1 = n1; //_node2 = n2;
483 _loopIndex = iLoop;
484 first = n1.Ptr();
485 second = n2.Ptr();
486 if ( first > second ) std::swap( first, second );
487 }
488 void setNext( _linkDef* next )
489 {
490 _next = next;
491 next->_prev = this;
492 }
493
494 friend std::ostream& operator<<(std::ostream& os, const _linkDef& link)
495 {
496 os << "Link def:\n";
497
498 os << link._node1;
499 if (link.first)
500 os << "first: " << link.first;
501
502 if (link.second)
503 os << "second: " << link.second;
504
505 os << "_loopIndex: " << link._loopIndex << '\n';
506
507 return os;
508 }
509 };
510 };
511
512 // topology of a hexahedron
513 static const std::size_t HEX_NODES_NUM = 8;
514 static const std::size_t HEX_LINKS_NUM = 12;
515 static const std::size_t HEX_QUADS_NUM = 6;
516 _Node _hexNodes [HEX_NODES_NUM];
517 _Link _hexLinks [HEX_LINKS_NUM];
518 _Face _hexQuads [HEX_QUADS_NUM];
519
520 // faces resulted from hexahedron intersection
521 std::vector< _Face > _polygons;
522
523 // intresections with EDGEs
524 std::vector< const StdMeshers::Cartesian3D::E_IntersectPoint* > _eIntPoints;
525
526 // additional nodes created at intersection points
527 std::vector< _Node > _intNodes;
528
529 // nodes inside the hexahedron (at VERTEXes) refer to _intNodes
530 std::vector< _Node* > _vIntNodes;
531
532 // computed volume elements
534
536 double _sideLength[3];
537 int _nbCornerNodes, _nbFaceIntNodes, _nbBndNodes;
538 int _origNodeInd; // index of _hexNodes[0] node within the _grid
539 size_t _i,_j,_k;
542
543 public:
545 int MakeElements(SMESH_MesherHelper& helper,
546 const TEdge2faceIDsMap& edge2faceIDsMap,
547 const int numOfThreads = 1 );
548 void computeElements( const Solid* solid = 0, int solidIndex = -1 );
549
550 private:
551 Hexahedron(const Hexahedron& other, size_t i, size_t j, size_t k, int cellID );
552 void init( size_t i, size_t j, size_t k, const Solid* solid=0 );
553 void init( size_t i );
554 void clearNodesLinkedToNull(const Solid* solid, SMESH_MesherHelper& helper);
555 bool isSplittedLink(const Solid* solid, SMESH_MesherHelper& helper, const Hexahedron::_Link& linkIn) const;
556 void setIJK( size_t i );
557 /*Auxiliary methods to extract operations from monolitic compute method*/
558 void defineHexahedralFaces( const Solid* solid, const IsInternalFlag intFlag );
559 bool compute( const Solid* solid, const IsInternalFlag intFlag );
560 size_t getSolids( StdMeshers::Cartesian3D::TGeomID ids[] );
561 bool isCutByInternalFace( IsInternalFlag & maxFlag );
562 void addEdges(SMESH_MesherHelper& helper,
563 std::vector< Hexahedron* >& intersectedHex,
564 const TEdge2faceIDsMap& edge2faceIDsMap);
565 gp_Pnt findIntPoint( double u1, double proj1, double u2, double proj2,
566 double proj, BRepAdaptor_Curve& curve,
567 const gp_XYZ& axis, const gp_XYZ& origin );
568 int getEntity( const StdMeshers::Cartesian3D::E_IntersectPoint* ip, int* facets, int& sub );
569 bool addIntersection( const StdMeshers::Cartesian3D::E_IntersectPoint* ip,
570 std::vector< Hexahedron* >& hexes,
571 int ijk[], int dIJK[] );
572 bool isQuadOnFace( const size_t iQuad );
573 bool findChain( _Node* n1, _Node* n2, _Face& quad, std::vector<_Node*>& chainNodes );
574 bool closePolygon( _Face* polygon, std::vector<_Node*>& chainNodes ) const;
575 bool findChainOnEdge( const std::vector< _OrientedLink >& splits,
576 const _OrientedLink& prevSplit,
577 const _OrientedLink& avoidSplit,
578 const std::set< StdMeshers::Cartesian3D::TGeomID > & concaveFaces,
579 size_t & iS,
580 _Face& quad,
581 std::vector<_Node*>& chn);
582 typedef std::pair< StdMeshers::Cartesian3D::TGeomID, int > TFaceOfLink; // (face, link)
583 static TFaceOfLink findStartLink(const std::vector< _OrientedLink* >& freeLinks,
584 std::set< StdMeshers::Cartesian3D::TGeomID >& usedFaceIDs);
585 size_t findCoplanarPolygon
586 (const _Face& thePolygon,
587 const size_t nbQuadPolygons,
588 std::vector< _OrientedLink* >& freeLinks,
589 int& nbFreeLinks,
590 const E_IntersectPoint& ipTmp,
591 std::set< StdMeshers::Cartesian3D::TGeomID >& usedFaceIDs,
592 std::map< StdMeshers::Cartesian3D::TGeomID, std::vector< const B_IntersectPoint* > >& tmpAddedFace,
593 const StdMeshers::Cartesian3D::TGeomID& curFace);
594 int addVolumes( SMESH_MesherHelper& helper );
595 void addFaces( SMESH_MesherHelper& helper,
596 const std::vector< const SMDS_MeshElement* > & boundaryVolumes );
597 void addSegments( SMESH_MesherHelper& helper,
598 const TEdge2faceIDsMap& edge2faceIDsMap );
599 void getVolumes( std::vector< const SMDS_MeshElement* > & volumes );
600 void getBoundaryElems( std::vector< const SMDS_MeshElement* > & boundaryVolumes );
601 void removeExcessSideDivision(const std::vector< Hexahedron* >& allHexa);
602 void removeExcessNodes(std::vector< Hexahedron* >& allHexa);
603 void preventVolumesOverlapping();
604 StdMeshers::Cartesian3D::TGeomID getAnyFace() const;
605 void cutByExtendedInternal( std::vector< Hexahedron* >& hexes,
606 const TColStd_MapOfInteger& intEdgeIDs );
607 gp_Pnt mostDistantInternalPnt( int hexIndex, const gp_Pnt& p1, const gp_Pnt& p2 );
608 bool isOutPoint( _Link& link, int iP, SMESH_MesherHelper& helper, const Solid* solid ) const;
609 void sortVertexNodes(std::vector<_Node*>& nodes,
610 _Node* curNode,
612 bool isInHole() const;
613 bool hasStrangeEdge() const;
614 bool checkPolyhedronSize( bool isCutByInternalFace, double & volSize ) const;
615 int checkPolyhedronValidity( _volumeDef* volDef, std::vector<std::vector<int>>& splitQuantities,
616 std::vector<std::vector<const SMDS_MeshNode*>>& splitNodes );
617 const SMDS_MeshElement* addPolyhedronToMesh( _volumeDef* volDef,
618 SMESH_MesherHelper& helper,
619 const std::vector<const SMDS_MeshNode*>& nodes,
620 const std::vector<int>& quantities );
621 bool addHexa ();
622 bool addTetra();
623 bool addPenta();
624 bool addPyra ();
625 bool debugDumpLink( _Link* link );
626 _Node* findEqualNode( std::vector< _Node* >& nodes,
628 const double tol2 )
629 {
630 for ( size_t i = 0; i < nodes.size(); ++i )
631 if ( nodes[i]->EdgeIntPnt() == ip ||
632 nodes[i]->Point().SquareDistance( ip->_point ) <= tol2 )
633 return nodes[i];
634 return 0;
635 }
636 bool isCorner( const _Node* node ) const { return ( node >= &_hexNodes[0] &&
637 node - &_hexNodes[0] < 8 ); }
638 bool hasEdgesAround( const ConcaveFace* cf ) const;
639 bool isImplementEdges() const { return _grid->_edgeIntPool.nbElements(); }
640 bool isOutParam(const double uvw[3]) const;
641
642 typedef boost::container::flat_map< StdMeshers::Cartesian3D::TGeomID, size_t > TID2Nb;
644 {
645 TID2Nb::value_type s0( id, 0 );
646 TID2Nb::iterator id2nb = id2nbMap.insert( s0 ).first;
647 id2nb->second++;
648 }
649 }; // class Hexahedron
650} // end namespace Cartesian3D
651} // end namespace StdMeshers
652
653#endif
#define STDMESHERS_EXPORT
Definition: SMESH_StdMeshers.hxx:38
SMESH_TNodeXYZ SMESH_NodeXYZ
Definition: SMESH_TypeDefs.hxx:240
void reverse(vector< T > &vec)
reverse order of vector elements
Definition: StdMeshers_FaceSide.cxx:941
Base class for elements.
Definition: SMDS_MeshElement.hxx:56
Definition: SMDS_MeshNode.hxx:36
virtual void Print(std::ostream &OS) const override
Print self.
Definition: SMDS_MeshNode.cxx:68
Definition: SMESH_Block.hxx:63
TShapeID
Definition: SMESH_Block.hxx:65
It helps meshers to add elements and provides other utilities.
Definition: SMESH_MesherHelper.hxx:84
Definition: StdMeshers_Cartesian_3D_Grid.hxx:414
ObjectPool< E_IntersectPoint > _edgeIntPool
Definition: StdMeshers_Cartesian_3D_Grid.hxx:430
Class representing topology of the hexahedron and creating a mesh volume basing on analysis of hexahe...
Definition: StdMeshers_Cartesian_3D_Hexahedron.hxx:95
static void insertAndIncrement(StdMeshers::Cartesian3D::TGeomID id, TID2Nb &id2nbMap)
Definition: StdMeshers_Cartesian_3D_Hexahedron.hxx:643
std::vector< _Node > _intNodes
Definition: StdMeshers_Cartesian_3D_Hexahedron.hxx:527
size_t _i
Definition: StdMeshers_Cartesian_3D_Hexahedron.hxx:539
bool isImplementEdges() const
Definition: StdMeshers_Cartesian_3D_Hexahedron.hxx:639
std::vector< const StdMeshers::Cartesian3D::E_IntersectPoint * > _eIntPoints
Definition: StdMeshers_Cartesian_3D_Hexahedron.hxx:524
std::vector< _Face > _polygons
Definition: StdMeshers_Cartesian_3D_Hexahedron.hxx:521
IsInternalFlag
Definition: StdMeshers_Cartesian_3D_Hexahedron.hxx:99
_Node * findEqualNode(std::vector< _Node * > &nodes, const StdMeshers::Cartesian3D::E_IntersectPoint *ip, const double tol2)
Definition: StdMeshers_Cartesian_3D_Hexahedron.hxx:626
bool _hasTooSmall
Definition: StdMeshers_Cartesian_3D_Hexahedron.hxx:540
bool isCorner(const _Node *node) const
Definition: StdMeshers_Cartesian_3D_Hexahedron.hxx:636
int _nbBndNodes
Definition: StdMeshers_Cartesian_3D_Hexahedron.hxx:537
int _origNodeInd
Definition: StdMeshers_Cartesian_3D_Hexahedron.hxx:538
std::vector< _Node * > _vIntNodes
Definition: StdMeshers_Cartesian_3D_Hexahedron.hxx:530
int _cellID
Definition: StdMeshers_Cartesian_3D_Hexahedron.hxx:541
StdMeshers::Cartesian3D::Grid * _grid
Definition: StdMeshers_Cartesian_3D_Hexahedron.hxx:535
std::pair< StdMeshers::Cartesian3D::TGeomID, int > TFaceOfLink
Definition: StdMeshers_Cartesian_3D_Hexahedron.hxx:582
boost::container::flat_map< StdMeshers::Cartesian3D::TGeomID, size_t > TID2Nb
Definition: StdMeshers_Cartesian_3D_Hexahedron.hxx:642
_volumeDef _volumeDefs
Definition: StdMeshers_Cartesian_3D_Hexahedron.hxx:533
void getVolumes(std::vector< const SMDS_MeshElement * > &volumes)
Container of IDs of SOLID sub-shapes.
Definition: StdMeshers_Cartesian_3D_Grid.hxx:167
@ Node
Selection of mesh nodes.
Definition: libSMESH_Swig.h:52
ENUM Add(ENUM v, int delta)
Return incremented enum value.
Definition: SMESH_TypeDefs.hxx:140
int TGeomID
Definition: StdMeshers_Cartesian_3D_Grid.hxx:123
std::map< TGeomID, std::vector< TGeomID > > TEdge2faceIDsMap
Definition: StdMeshers_Cartesian_3D_Grid.hxx:127
StdMeshers: interfaces to standard hypotheses and algorithms.
Definition: StdMeshers_Cartesian_3D_Grid.hxx:120
Common data of any intersection between a Grid and a shape.
Definition: StdMeshers_Cartesian_3D_Grid.hxx:284
const SMDS_MeshNode * _node
Definition: StdMeshers_Cartesian_3D_Grid.hxx:289
size_t GetCommonFaces(const B_IntersectPoint *other, TGeomID *commonFaces) const
Definition: StdMeshers_Cartesian_3D_Grid.cxx:194
std::vector< TGeomID > _faceIDs
Definition: StdMeshers_Cartesian_3D_Grid.hxx:290
TGeomID HasCommonFace(const B_IntersectPoint *other, TGeomID avoidFace=-1) const
Definition: StdMeshers_Cartesian_3D_Grid.cxx:181
bool IsOnFace(TGeomID faceID) const
Definition: StdMeshers_Cartesian_3D_Grid.cxx:210
Sub-entities of a FACE neighboring its concave VERTEX.
Definition: StdMeshers_Cartesian_3D_Grid.hxx:149
Data of intersection between GridPlanes and a TopoDS_EDGE.
Definition: StdMeshers_Cartesian_3D_Grid.hxx:321
gp_Pnt _point
Definition: StdMeshers_Cartesian_3D_Grid.hxx:322
Data of intersection between a GridLine and a TopoDS_Face.
Definition: StdMeshers_Cartesian_3D_Grid.hxx:305
Definition: StdMeshers_Cartesian_3D_Hexahedron.hxx:333
friend std::ostream & operator<<(std::ostream &os, const _Face &face)
Definition: StdMeshers_Cartesian_3D_Hexahedron.hxx:365
_Face()
Definition: StdMeshers_Cartesian_3D_Hexahedron.hxx:339
void AddPolyLink(_Node *n0, _Node *n1, _Face *faceToFindEqual=0)
Definition: StdMeshers_Cartesian_3D_Hexahedron.hxx:346
SMESH_Block::TShapeID _name
Definition: StdMeshers_Cartesian_3D_Hexahedron.hxx:334
bool IsPolyLink(const _OrientedLink &ol)
Definition: StdMeshers_Cartesian_3D_Hexahedron.hxx:341
std::vector< _OrientedLink > _links
Definition: StdMeshers_Cartesian_3D_Hexahedron.hxx:335
std::vector< _Link > _polyLinks
Definition: StdMeshers_Cartesian_3D_Hexahedron.hxx:336
std::vector< _Node * > _eIntNodes
Definition: StdMeshers_Cartesian_3D_Hexahedron.hxx:337
< node either at a hexahedron corner or at intersection
Definition: StdMeshers_Cartesian_3D_Hexahedron.hxx:102
StdMeshers::Cartesian3D::TGeomID face(size_t i) const
Definition: StdMeshers_Cartesian_3D_Hexahedron.hxx:120
const SMDS_MeshNode * Node() const
Definition: StdMeshers_Cartesian_3D_Hexahedron.hxx:111
_Node(const SMDS_MeshNode *n=0, const StdMeshers::Cartesian3D::B_IntersectPoint *ip=0)
Definition: StdMeshers_Cartesian_3D_Hexahedron.hxx:109
friend std::ostream & operator<<(std::ostream &os, const _Node &node)
Definition: StdMeshers_Cartesian_3D_Hexahedron.hxx:161
const _Face * _usedInFace
Definition: StdMeshers_Cartesian_3D_Hexahedron.hxx:106
bool IsOnFace(StdMeshers::Cartesian3D::TGeomID faceID) const
Definition: StdMeshers_Cartesian_3D_Hexahedron.hxx:132
const StdMeshers::Cartesian3D::E_IntersectPoint * EdgeIntPnt() const
Definition: StdMeshers_Cartesian_3D_Hexahedron.hxx:115
StdMeshers::Cartesian3D::TGeomID ShapeID() const
Definition: StdMeshers_Cartesian_3D_Hexahedron.hxx:150
gp_Pnt Point() const
Definition: StdMeshers_Cartesian_3D_Hexahedron.hxx:141
size_t GetCommonFaces(const StdMeshers::Cartesian3D::B_IntersectPoint *other, StdMeshers::Cartesian3D::TGeomID *common) const
Definition: StdMeshers_Cartesian_3D_Hexahedron.hxx:136
bool IsUsedInFace(const _Face *polygon=0)
Definition: StdMeshers_Cartesian_3D_Hexahedron.hxx:123
const SMDS_MeshNode * _boundaryCornerNode
Definition: StdMeshers_Cartesian_3D_Hexahedron.hxx:104
void SetInternal(IsInternalFlag intFlag)
Definition: StdMeshers_Cartesian_3D_Hexahedron.hxx:121
const StdMeshers::Cartesian3D::B_IntersectPoint * _intPoint
Definition: StdMeshers_Cartesian_3D_Hexahedron.hxx:105
bool IsCutByInternal() const
Definition: StdMeshers_Cartesian_3D_Hexahedron.hxx:122
const StdMeshers::Cartesian3D::F_IntersectPoint * FaceIntPnt() const
Definition: StdMeshers_Cartesian_3D_Hexahedron.hxx:117
const std::vector< StdMeshers::Cartesian3D::TGeomID > & faces() const
Definition: StdMeshers_Cartesian_3D_Hexahedron.hxx:119
const SMDS_MeshNode * _node
Definition: StdMeshers_Cartesian_3D_Hexahedron.hxx:103
char _isInternalFlags
Definition: StdMeshers_Cartesian_3D_Hexahedron.hxx:107
const SMDS_MeshNode * BoundaryNode() const
Definition: StdMeshers_Cartesian_3D_Hexahedron.hxx:113
StdMeshers::Cartesian3D::TGeomID IsLinked(const StdMeshers::Cartesian3D::B_IntersectPoint *other, StdMeshers::Cartesian3D::TGeomID avoidFace=-1) const
Definition: StdMeshers_Cartesian_3D_Hexahedron.hxx:127
Definition: StdMeshers_Cartesian_3D_Hexahedron.hxx:297
int _iCheckIteration
Definition: StdMeshers_Cartesian_3D_Hexahedron.hxx:300
bool IsCheckedOrUsed(bool used) const
Definition: StdMeshers_Cartesian_3D_Hexahedron.hxx:308
_Link * _checkedSplit
Definition: StdMeshers_Cartesian_3D_Hexahedron.hxx:301
_Split(_Link &split, int iLink)
Definition: StdMeshers_Cartesian_3D_Hexahedron.hxx:304
bool _isUsed
Definition: StdMeshers_Cartesian_3D_Hexahedron.hxx:302
int _linkID
Definition: StdMeshers_Cartesian_3D_Hexahedron.hxx:298
set to _hexLinks splits on one side of INTERNAL FACEs
Definition: StdMeshers_Cartesian_3D_Hexahedron.hxx:295
std::vector< _Split > _splits
Definition: StdMeshers_Cartesian_3D_Hexahedron.hxx:311
size_t _nbUsed
Definition: StdMeshers_Cartesian_3D_Hexahedron.hxx:314
bool More() const
Definition: StdMeshers_Cartesian_3D_Hexahedron.hxx:327
_Link * _hexLinks
Definition: StdMeshers_Cartesian_3D_Hexahedron.hxx:310
std::vector< _Node * > _freeNodes
Definition: StdMeshers_Cartesian_3D_Hexahedron.hxx:315
_SplitIterator(_Link *hexLinks)
Definition: StdMeshers_Cartesian_3D_Hexahedron.hxx:317
int _iterationNb
Definition: StdMeshers_Cartesian_3D_Hexahedron.hxx:312
size_t _nbChecked
Definition: StdMeshers_Cartesian_3D_Hexahedron.hxx:313
Definition: StdMeshers_Cartesian_3D_Hexahedron.hxx:473
_nodeDef _node1
Definition: StdMeshers_Cartesian_3D_Hexahedron.hxx:474
_linkDef * _next
Definition: StdMeshers_Cartesian_3D_Hexahedron.hxx:475
_linkDef()
Definition: StdMeshers_Cartesian_3D_Hexahedron.hxx:478
_linkDef * _prev
Definition: StdMeshers_Cartesian_3D_Hexahedron.hxx:475
friend std::ostream & operator<<(std::ostream &os, const _linkDef &link)
Definition: StdMeshers_Cartesian_3D_Hexahedron.hxx:494
void init(const _nodeDef &n1, const _nodeDef &n2, size_t iLoop)
Definition: StdMeshers_Cartesian_3D_Hexahedron.hxx:480
size_t _loopIndex
Definition: StdMeshers_Cartesian_3D_Hexahedron.hxx:476
void setNext(_linkDef *next)
Definition: StdMeshers_Cartesian_3D_Hexahedron.hxx:488
Definition: StdMeshers_Cartesian_3D_Hexahedron.hxx:400
bool operator==(const _nodeDef &other) const
Definition: StdMeshers_Cartesian_3D_Hexahedron.hxx:411
_ptr Ptr() const
Definition: StdMeshers_Cartesian_3D_Hexahedron.hxx:410
const StdMeshers::Cartesian3D::B_IntersectPoint * _intPoint
Definition: StdMeshers_Cartesian_3D_Hexahedron.hxx:402
_nodeDef()
Definition: StdMeshers_Cartesian_3D_Hexahedron.hxx:404
_nodeDef(_Node *n)
Definition: StdMeshers_Cartesian_3D_Hexahedron.hxx:405
friend std::ostream & operator<<(std::ostream &os, const _nodeDef &node)
Definition: StdMeshers_Cartesian_3D_Hexahedron.hxx:413
const StdMeshers::Cartesian3D::E_IntersectPoint * EdgeIntPnt() const
Definition: StdMeshers_Cartesian_3D_Hexahedron.hxx:408
const SMDS_MeshNode * _node
Definition: StdMeshers_Cartesian_3D_Hexahedron.hxx:401
const SMDS_MeshNode * Node() const
Definition: StdMeshers_Cartesian_3D_Hexahedron.hxx:406
Definition: StdMeshers_Cartesian_3D_Hexahedron.hxx:396
~_volumeDef()
Definition: StdMeshers_Cartesian_3D_Hexahedron.hxx:442
std::vector< _nodeDef > _nodes
Definition: StdMeshers_Cartesian_3D_Hexahedron.hxx:432
StdMeshers::Cartesian3D::TGeomID _solidID
Definition: StdMeshers_Cartesian_3D_Hexahedron.hxx:435
void SetNext(_volumeDef *vd)
Definition: StdMeshers_Cartesian_3D_Hexahedron.hxx:455
bool IsPolyhedron() const
Definition: StdMeshers_Cartesian_3D_Hexahedron.hxx:460
std::vector< SMESH_Block::TShapeID > _names
Definition: StdMeshers_Cartesian_3D_Hexahedron.hxx:439
_volumeDef(_volumeDef &other)
Definition: StdMeshers_Cartesian_3D_Hexahedron.hxx:443
void * _ptr
Definition: StdMeshers_Cartesian_3D_Hexahedron.hxx:397
void Set(_Node **nodes, int nb)
Definition: StdMeshers_Cartesian_3D_Hexahedron.hxx:452
double _size
Definition: StdMeshers_Cartesian_3D_Hexahedron.hxx:436
_volumeDef * at(int index)
Definition: StdMeshers_Cartesian_3D_Hexahedron.hxx:449
bool IsEmpty() const
Definition: StdMeshers_Cartesian_3D_Hexahedron.hxx:458
_volumeDef()
Definition: StdMeshers_Cartesian_3D_Hexahedron.hxx:441
const SMDS_MeshElement * _volume
Definition: StdMeshers_Cartesian_3D_Hexahedron.hxx:437
std::vector< int > _quantities
Definition: StdMeshers_Cartesian_3D_Hexahedron.hxx:433
std::vector< const SMDS_MeshElement * > _brotherVolume
Definition: StdMeshers_Cartesian_3D_Hexahedron.hxx:438
size_t size() const
Definition: StdMeshers_Cartesian_3D_Hexahedron.hxx:448
_volumeDef * _next
Definition: StdMeshers_Cartesian_3D_Hexahedron.hxx:434