1 // Copyright (C) 2005 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
2 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
4 // This library is free software; you can redistribute it and/or
5 // modify it under the terms of the GNU Lesser General Public
6 // License as published by the Free Software Foundation; either
7 // version 2.1 of the License.
9 // This library is distributed in the hope that it will be useful
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 // Lesser General Public License for more details.
14 // You should have received a copy of the GNU Lesser General Public
15 // License along with this library; if not, write to the Free Software
16 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
20 // File: SMESH_MesherHelper.hxx
21 // Created: 15.02.06 14:48:09
22 // Author: Sergey KUUL
25 #ifndef SMESH_MesherHelper_HeaderFile
26 #define SMESH_MesherHelper_HeaderFile
28 #include <SMESH_Mesh.hxx>
29 #include <TopoDS_Shape.hxx>
30 #include <SMDS_MeshNode.hxx>
31 #include <TopoDS_Face.hxx>
32 #include <gp_Pnt2d.hxx>
33 #include <SMDS_QuadraticEdge.hxx>
37 typedef pair<const SMDS_MeshNode*, const SMDS_MeshNode*> NLink;
38 typedef map<NLink, const SMDS_MeshNode*> NLinkNodeMap;
39 typedef map<NLink, const SMDS_MeshNode*>::iterator ItNLinkNode;
42 * \brief It helps meshers to add elements
44 * It allow meshers not to care about creation of medium nodes
45 * when filling a quadratic mesh. Helper does it itself.
46 * It defines degree of elements to create when IsQuadraticSubMesh()
50 typedef std::vector<const SMDS_MeshNode* > TNodeColumn;
51 typedef std::map< double, TNodeColumn > TParam2ColumnMap;
53 class SMESH_MesherHelper
56 // ---------- PUBLIC UTILITIES ----------
59 * \brief Returns true if given node is medium
60 * \param n - node to check
61 * \param typeToCheck - type of elements containing the node to ask about node status
62 * \retval bool - check result
64 static bool IsMedium(const SMDS_MeshNode* node,
65 const SMDSAbs_ElementType typeToCheck = SMDSAbs_All);
68 * \brief Load nodes bound to face into a map of node columns
69 * \param theParam2ColumnMap - map of node columns to fill
70 * \param theFace - the face on which nodes are searched for
71 * \param theBaseEdge - the edge nodes of which are columns' bases
72 * \param theMesh - the mesh containing nodes
73 * \retval bool - false if something is wrong
75 * The key of the map is a normalized parameter of each
76 * base node on theBaseEdge.
77 * This method works in supposition that nodes on the face
78 * forms a rectangular grid and elements can be quardrangles or triangles
80 static bool LoadNodeColumns(TParam2ColumnMap & theParam2ColumnMap,
81 const TopoDS_Face& theFace,
82 const TopoDS_Edge& theBaseEdge,
83 SMESHDS_Mesh* theMesh);
85 * \brief Return support shape of a node
86 * \param node - the node
87 * \param meshDS - mesh DS
88 * \retval TopoDS_Shape - found support shape
90 static const TopoDS_Shape& GetSubShapeByNode(const SMDS_MeshNode* node,
92 { return meshDS->IndexToShape( node->GetPosition()->GetShapeId() ); }
95 * \brief Return a valid node index, fixing the given one if necessary
96 * \param ind - node index
97 * \param nbNodes - total nb of nodes
98 * \retval int - valid node index
100 static int WrapIndex(const int ind, const int nbNodes) {
101 if ( ind < 0 ) return nbNodes + ind % nbNodes;
102 if ( ind >= nbNodes ) return ind % nbNodes;
107 // ---------- PUBLIC INSTANCE METHODS ----------
110 SMESH_MesherHelper(SMESH_Mesh& theMesh);
112 SMESH_Mesh* GetMesh() const { return myMesh; }
114 SMESHDS_Mesh* GetMeshDS() const { return GetMesh()->GetMeshDS(); }
117 * Check submesh for given shape: if all elements on this shape are quadratic,
118 * quadratic elements will be created. Also fill myNLinkNodeMap
120 bool IsQuadraticSubMesh(const TopoDS_Shape& theShape);
122 * \brief Set order of elements to create without calling IsQuadraticSubMesh()
124 void SetIsQuadratic(const bool theBuildQuadratic)
125 { myCreateQuadratic = theBuildQuadratic; }
127 * \brief Return myCreateQuadratic flag
129 bool GetIsQuadratic() const { return myCreateQuadratic; }
132 * \brief To set created elements on the shape set by IsQuadraticSubMesh()
133 * or the next methods. By defaul elements are set on the shape if
134 * a mesh has no shape to be meshed
136 void SetElementsOnShape(bool toSet) { mySetElemOnShape = toSet; }
139 * \brief Set shape to make elements on without calling IsQuadraticSubMesh()
141 void SetSubShape(const int subShapeID);//!==SMESHDS_Mesh::ShapeToIndex(shape)
142 void SetSubShape(const TopoDS_Shape& subShape);
144 * \brief Return ID of the shape set by IsQuadraticSubMesh() or SetSubShape()
145 * \retval int - shape index in SMESHDS
147 int GetSubShapeID() const { return myShapeID; }
149 * \brief Return the shape set by IsQuadraticSubMesh() or SetSubShape()
151 TopoDS_Shape GetSubShape() const { return myShape; }
156 SMDS_MeshNode* AddNode(double x, double y, double z, int ID = 0);
158 * Creates quadratic or linear edge
160 SMDS_MeshEdge* AddEdge(const SMDS_MeshNode* n1,
161 const SMDS_MeshNode* n2,
163 const bool force3d = true);
165 * Creates quadratic or linear triangle
167 SMDS_MeshFace* AddFace(const SMDS_MeshNode* n1,
168 const SMDS_MeshNode* n2,
169 const SMDS_MeshNode* n3,
171 const bool force3d = false);
173 * Creates quadratic or linear quadrangle
175 SMDS_MeshFace* AddFace(const SMDS_MeshNode* n1,
176 const SMDS_MeshNode* n2,
177 const SMDS_MeshNode* n3,
178 const SMDS_MeshNode* n4,
180 const bool force3d = false);
182 * Creates quadratic or linear tetraahedron
184 SMDS_MeshVolume* AddVolume(const SMDS_MeshNode* n1,
185 const SMDS_MeshNode* n2,
186 const SMDS_MeshNode* n3,
187 const SMDS_MeshNode* n4,
189 const bool force3d = true);
191 * Creates quadratic or linear pyramid
193 SMDS_MeshVolume* AddVolume(const SMDS_MeshNode* n1,
194 const SMDS_MeshNode* n2,
195 const SMDS_MeshNode* n3,
196 const SMDS_MeshNode* n4,
197 const SMDS_MeshNode* n5,
199 const bool force3d = true);
201 * Creates quadratic or linear pentahedron
203 SMDS_MeshVolume* AddVolume(const SMDS_MeshNode* n1,
204 const SMDS_MeshNode* n2,
205 const SMDS_MeshNode* n3,
206 const SMDS_MeshNode* n4,
207 const SMDS_MeshNode* n5,
208 const SMDS_MeshNode* n6,
210 const bool force3d = true);
212 * Creates quadratic or linear hexahedron
214 SMDS_MeshVolume* AddVolume(const SMDS_MeshNode* n1,
215 const SMDS_MeshNode* n2,
216 const SMDS_MeshNode* n3,
217 const SMDS_MeshNode* n4,
218 const SMDS_MeshNode* n5,
219 const SMDS_MeshNode* n6,
220 const SMDS_MeshNode* n7,
221 const SMDS_MeshNode* n8,
223 bool force3d = true);
225 * \brief Return U of the given node on the edge
227 double GetNodeU(const TopoDS_Edge& theEdge,
228 const SMDS_MeshNode* theNode);
230 * \brief Return node UV on face
231 * \param inFaceNode - a node of element being created located inside a face
233 gp_XY GetNodeUV(const TopoDS_Face& F,
234 const SMDS_MeshNode* n,
235 const SMDS_MeshNode* inFaceNode=0) const;
237 * \brief Check if inFaceNode argument is necessary for call GetNodeUV(F,..)
238 * \retval bool - return true if the face is periodic
240 * if F is Null, answer about subshape set through IsQuadraticSubMesh() or
243 bool GetNodeUVneedInFaceNode(const TopoDS_Face& F = TopoDS_Face()) const;
246 * \brief Check if shape is a degenerated edge or it's vertex
247 * \param subShape - edge or vertex index in SMESHDS
248 * \retval bool - true if subShape is a degenerated shape
250 * It works only if IsQuadraticSubMesh() or SetSubShape() has been called
252 bool IsDegenShape(const int subShape) const
253 { return myDegenShapeIds.find( subShape ) != myDegenShapeIds.end(); }
255 * \brief Check if shape is a seam edge or it's vertex
256 * \param subShape - edge or vertex index in SMESHDS
257 * \retval bool - true if subShape is a seam shape
259 * It works only if IsQuadraticSubMesh() or SetSubShape() has been called
261 bool IsSeamShape(const int subShape) const
262 { return mySeamShapeIds.find( subShape ) != mySeamShapeIds.end(); }
264 * \brief Check if shape is a seam edge or it's vertex
265 * \param subShape - edge or vertex
266 * \retval bool - true if subShape is a seam shape
268 * It works only if IsQuadraticSubMesh() or SetSubShape() has been called
270 bool IsSeamShape(const TopoDS_Shape& subShape) const
271 { return IsSeamShape( GetMeshDS()->ShapeToIndex( subShape )); }
273 * \brief Check if the shape set through IsQuadraticSubMesh() or SetSubShape()
275 * \retval bool - true if it has
277 bool HasSeam() const { return !mySeamShapeIds.empty(); }
279 * \brief Return index of periodic parametric direction of a closed face
280 * \retval int - 1 for U, 2 for V direction
282 int GetPeriodicIndex() const { return myParIndex; }
285 * Special function for search or creation medium node
287 const SMDS_MeshNode* GetMediumNode(const SMDS_MeshNode* n1,
288 const SMDS_MeshNode* n2,
291 * Auxilary function for filling myNLinkNodeMap
293 void AddNLinkNode(const SMDS_MeshNode* n1,
294 const SMDS_MeshNode* n2,
295 const SMDS_MeshNode* n12);
297 * Auxilary function for filling myNLinkNodeMap
299 void AddNLinkNodeMap(const NLinkNodeMap& aMap)
300 { myNLinkNodeMap.insert(aMap.begin(), aMap.end()); }
303 * Returns myNLinkNodeMap
305 const NLinkNodeMap& GetNLinkNodeMap() const { return myNLinkNodeMap; }
310 * \brief Select UV on either of 2 pcurves of a seam edge, closest to the given UV
311 * \param uv1 - UV on the seam
312 * \param uv2 - UV within a face
313 * \retval gp_Pnt2d - selected UV
315 gp_Pnt2d GetUVOnSeam( const gp_Pnt2d& uv1, const gp_Pnt2d& uv2 ) const;
319 // Forbiden copy constructor
320 SMESH_MesherHelper (const SMESH_MesherHelper& theOther) {};
322 // special map for using during creation of quadratic elements
323 NLinkNodeMap myNLinkNodeMap;
325 std::set< int > myDegenShapeIds;
326 std::set< int > mySeamShapeIds;
327 double myPar1, myPar2; // bounds of a closed periodic surface
328 int myParIndex; // bounds' index (1-U, 2-V)
330 TopoDS_Shape myShape;
334 // to create quadratic elements
335 bool myCreateQuadratic;
336 bool mySetElemOnShape;