Salome HOME
Update mail address
[modules/smesh.git] / src / SMESH / SMESH_MeshEditor.hxx
1 //  SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses
2 //
3 //  Copyright (C) 2003  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 //  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS 
5 // 
6 //  This library is free software; you can redistribute it and/or 
7 //  modify it under the terms of the GNU Lesser General Public 
8 //  License as published by the Free Software Foundation; either 
9 //  version 2.1 of the License. 
10 // 
11 //  This library is distributed in the hope that it will be useful, 
12 //  but WITHOUT ANY WARRANTY; without even the implied warranty of 
13 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 
14 //  Lesser General Public License for more details. 
15 // 
16 //  You should have received a copy of the GNU Lesser General Public 
17 //  License along with this library; if not, write to the Free Software 
18 //  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA 
19 // 
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
21 //
22 //
23 //
24 // File      : SMESH_MeshEditor.hxx
25 // Created   : Mon Apr 12 14:56:19 2004
26 // Author    : Edward AGAPOV (eap)
27 // Module    : SMESH
28
29
30 #ifndef SMESH_MeshEditor_HeaderFile
31 #define SMESH_MeshEditor_HeaderFile
32
33 #include "SMESH_Mesh.hxx"
34 #include "SMESH_Controls.hxx"
35 #include "SMESH_SequenceOfNode.hxx"
36 #include "SMESH_SequenceOfElemPtr.hxx"
37 #include "gp_Dir.hxx"
38 #include "TColStd_HSequenceOfReal.hxx"
39 #include "SMESH_MesherHelper.hxx"
40
41 #include <list>
42 #include <map>
43
44 typedef map<const SMDS_MeshElement*,
45             list<const SMDS_MeshElement*> > TElemOfElemListMap;
46
47 typedef map<const SMDS_MeshNode*, SMESHDS_SubMesh*> RemoveQuadNodeMap;
48 typedef map<const SMDS_MeshNode*, SMESHDS_SubMesh*>::iterator ItRemoveQuadNodeMap;
49
50 class SMDS_MeshElement;
51 class SMDS_MeshFace;
52 class SMDS_MeshNode;
53 class gp_Ax1;
54 class gp_Vec;
55 class gp_Pnt;
56
57 class SMESH_MeshEditor {
58  public:
59
60   SMESH_MeshEditor( SMESH_Mesh* theMesh );
61
62   bool Remove (const std::list< int >& theElemIDs, const bool isNodes);
63   // Remove a node or an element.
64   // Modify a compute state of sub-meshes which become empty
65
66   bool InverseDiag (const SMDS_MeshElement * theTria1,
67                     const SMDS_MeshElement * theTria2 );
68   // Replace two neighbour triangles with ones built on the same 4 nodes
69   // but having other common link.
70   // Return False if args are improper
71
72   bool InverseDiag (const SMDS_MeshNode * theNode1,
73                     const SMDS_MeshNode * theNode2 );
74   // Replace two neighbour triangles sharing theNode1-theNode2 link
75   // with ones built on the same 4 nodes but having other common link.
76   // Return false if proper faces not found
77
78   bool DeleteDiag (const SMDS_MeshNode * theNode1,
79                    const SMDS_MeshNode * theNode2 );
80   // Replace two neighbour triangles sharing theNode1-theNode2 link
81   // with a quadrangle built on the same 4 nodes.
82   // Return false if proper faces not found
83
84   bool Reorient (const SMDS_MeshElement * theElement);
85   // Reverse theElement orientation
86
87
88   /*!
89    * \brief Fuse neighbour triangles into quadrangles.
90    * \param theElems     - The triangles to be fused.
91    * \param theCriterion - Is used to choose a neighbour to fuse with.
92    * \param theMaxAngle  - Is a max angle between element normals at which fusion
93    *                       is still performed; theMaxAngle is mesured in radians.
94    * \retval bool - Success or not.
95    */
96   bool TriToQuad (std::map<int,const SMDS_MeshElement*> & theElems,
97                   SMESH::Controls::NumericalFunctorPtr theCriterion,
98                   const double                         theMaxAngle);
99
100   /*!
101    * \brief Split quadrangles into triangles.
102    * \param theElems     - The faces to be splitted.
103    * \param theCriterion - Is used to choose a diagonal for splitting.
104    * \retval bool - Success or not.
105    */
106   bool QuadToTri (std::map<int,const SMDS_MeshElement*> &  theElems,
107                   SMESH::Controls::NumericalFunctorPtr theCriterion);
108
109   /*!
110    * \brief Split quadrangles into triangles.
111    * \param theElems  - The faces to be splitted.
112    * \param the13Diag - Is used to choose a diagonal for splitting.
113    * \retval bool - Success or not.
114    */
115   bool QuadToTri (std::map<int,const SMDS_MeshElement*> & theElems,
116                   const bool                          the13Diag);
117
118   /*!
119    * \brief Find better diagonal for splitting.
120    * \param theQuad      - The face to find better splitting of.
121    * \param theCriterion - Is used to choose a diagonal for splitting.
122    * \retval int - 1 for 1-3 diagonal, 2 for 2-4, -1 - for errors.
123    */
124   int BestSplit (const SMDS_MeshElement*              theQuad,
125                  SMESH::Controls::NumericalFunctorPtr theCriterion);
126
127
128   enum SmoothMethod { LAPLACIAN = 0, CENTROIDAL };
129
130   void Smooth (std::map<int,const SMDS_MeshElement*> & theElements,
131                std::set<const SMDS_MeshNode*> &    theFixedNodes,
132                const SmoothMethod                  theSmoothMethod,
133                const int                           theNbIterations,
134                double                              theTgtAspectRatio = 1.0,
135                const bool                          the2D = true);
136   // Smooth theElements using theSmoothMethod during theNbIterations
137   // or until a worst element has aspect ratio <= theTgtAspectRatio.
138   // Aspect Ratio varies in range [1.0, inf].
139   // If theElements is empty, the whole mesh is smoothed.
140   // theFixedNodes contains additionally fixed nodes. Nodes built
141   // on edges and boundary nodes are always fixed.
142   // If the2D, smoothing is performed using UV parameters of nodes
143   // on geometrical faces
144
145
146   void RotationSweep (std::map<int,const SMDS_MeshElement*> & theElements,
147                       const gp_Ax1&                       theAxis,
148                       const double                        theAngle,
149                       const int                           theNbSteps,
150                       const double                        theToler);
151   // Generate new elements by rotation of theElements around theAxis
152   // by theAngle by theNbSteps
153
154   /*!
155    * Auxilary flag for advanced extrusion.
156    * BOUNDARY: create or not boundary for result of extrusion
157    * SEW:      try to use existing nodes or create new nodes in any case
158    */
159   enum ExtrusionFlags {
160     EXTRUSION_FLAG_BOUNDARY = 0x01,
161     EXTRUSION_FLAG_SEW = 0x02
162   };
163   
164   /*!
165    * special structire for control of extrusion functionality
166    */
167   struct ExtrusParam {
168     gp_Dir myDir; // direction of extrusion
169     Handle(TColStd_HSequenceOfReal) mySteps; // magnitudes for each step
170     SMESH_SequenceOfNode myNodes; // nodes for using in sewing
171   };
172
173   /*!
174    * Create new node in the mesh with given coordinates
175    * (auxilary for advanced extrusion)
176    */
177   const SMDS_MeshNode* CreateNode(const double x,
178                                   const double y,
179                                   const double z,
180                                   const double tolnode,
181                                   SMESH_SequenceOfNode& aNodes);
182
183   /*!
184    * Generate new elements by extrusion of theElements
185    * It is a method used in .idl file. All functionality
186    * is implemented in the next method (see below) which
187    * is used in the cuurent method.
188    * param theElems - list of elements for extrusion
189    * param newElemsMap returns history of extrusion
190    * param theFlags set flags for performing extrusion (see description
191    *   of enum ExtrusionFlags for additional information)
192    * param theTolerance - uses for comparing locations of nodes if flag
193    *   EXTRUSION_FLAG_SEW is set
194    */
195   void ExtrusionSweep
196            (map<int,const SMDS_MeshElement*> & theElems,
197             const gp_Vec&                  theStep,
198             const int                      theNbSteps,
199             TElemOfElemListMap&            newElemsMap,
200             const int                      theFlags = EXTRUSION_FLAG_BOUNDARY,
201             const double                   theTolerance = 1.e-6);
202   
203   /*!
204    * Generate new elements by extrusion of theElements
205    * param theElems - list of elements for extrusion
206    * param newElemsMap returns history of extrusion
207    * param theFlags set flags for performing extrusion (see description
208    *   of enum ExtrusionFlags for additional information)
209    * param theTolerance - uses for comparing locations of nodes if flag
210    *   EXTRUSION_FLAG_SEW is set
211    * param theParams - special structure for manage of extrusion
212    */
213   void ExtrusionSweep (map<int,const SMDS_MeshElement*> & theElems,
214                        ExtrusParam&                   theParams,
215                        TElemOfElemListMap&            newElemsMap,
216                        const int                      theFlags,
217                        const double                   theTolerance);
218
219
220   // Generate new elements by extrusion of theElements 
221   // by theStep by theNbSteps
222
223   enum Extrusion_Error {
224     EXTR_OK,
225     EXTR_NO_ELEMENTS, 
226     EXTR_PATH_NOT_EDGE,
227     EXTR_BAD_PATH_SHAPE,
228     EXTR_BAD_STARTING_NODE,
229     EXTR_BAD_ANGLES_NUMBER,
230     EXTR_CANT_GET_TANGENT
231     };
232   
233   Extrusion_Error ExtrusionAlongTrack (std::map<int,const SMDS_MeshElement*> & theElements,
234                                        SMESH_subMesh*                      theTrackPattern,
235                                        const SMDS_MeshNode*                theNodeStart,
236                                        const bool                          theHasAngles,
237                                        std::list<double>&                  theAngles,
238                                        const bool                          theHasRefPoint,
239                                        const gp_Pnt&                       theRefPoint);
240   // Generate new elements by extrusion of theElements along path given by theTrackPattern,
241   // theHasAngles are the rotation angles, base point can be given by theRefPoint
242
243   void Transform (std::map<int,const SMDS_MeshElement*> & theElements,
244                   const gp_Trsf&                      theTrsf,
245                   const bool                          theCopy);
246   // Move or copy theElements applying theTrsf to their nodes
247
248   typedef std::list< std::list< const SMDS_MeshNode* > > TListOfListOfNodes;
249
250   void FindCoincidentNodes (std::set<const SMDS_MeshNode*> & theNodes,
251                             const double                     theTolerance,
252                             TListOfListOfNodes &             theGroupsOfNodes);
253   // Return list of group of nodes close to each other within theTolerance.
254   // Search among theNodes or in the whole mesh if theNodes is empty.
255
256   int SimplifyFace (const vector<const SMDS_MeshNode *> faceNodes,
257                     vector<const SMDS_MeshNode *>&      poly_nodes,
258                     vector<int>&                        quantities) const;
259   // Split face, defined by <faceNodes>, into several faces by repeating nodes.
260   // Is used by MergeNodes()
261
262   void MergeNodes (TListOfListOfNodes & theNodeGroups);
263   // In each group, the cdr of nodes are substituted by the first one
264   // in all elements.
265
266   void MergeEqualElements();
267   // Remove all but one of elements built on the same nodes.
268   // Return nb of successfully merged groups.
269
270   static bool CheckFreeBorderNodes(const SMDS_MeshNode* theNode1,
271                                    const SMDS_MeshNode* theNode2,
272                                    const SMDS_MeshNode* theNode3 = 0);
273   // Return true if the three nodes are on a free border
274
275   enum Sew_Error {
276     SEW_OK,
277     // for SewFreeBorder()
278     SEW_BORDER1_NOT_FOUND,
279     SEW_BORDER2_NOT_FOUND,
280     SEW_BOTH_BORDERS_NOT_FOUND,
281     SEW_BAD_SIDE_NODES,
282     SEW_VOLUMES_TO_SPLIT,
283     // for SewSideElements()
284     SEW_DIFF_NB_OF_ELEMENTS,
285     SEW_TOPO_DIFF_SETS_OF_ELEMENTS,
286     SEW_BAD_SIDE1_NODES,
287     SEW_BAD_SIDE2_NODES
288     };
289     
290
291   Sew_Error SewFreeBorder (const SMDS_MeshNode* theBorderFirstNode,
292                            const SMDS_MeshNode* theBorderSecondNode,
293                            const SMDS_MeshNode* theBorderLastNode,
294                            const SMDS_MeshNode* theSide2FirstNode,
295                            const SMDS_MeshNode* theSide2SecondNode,
296                            const SMDS_MeshNode* theSide2ThirdNode = 0,
297                            const bool           theSide2IsFreeBorder = true,
298                            const bool           toCreatePolygons = false,
299                            const bool           toCreatePolyedrs = false);
300   // Sew the free border to the side2 by replacing nodes in
301   // elements on the free border with nodes of the elements
302   // of the side 2. If nb of links in the free border and
303   // between theSide2FirstNode and theSide2LastNode are different,
304   // additional nodes are inserted on a link provided that no
305   // volume elements share the splitted link.
306   // The side 2 is a free border if theSide2IsFreeBorder == true.
307   // Sewing is peformed between the given first, second and last
308   // nodes on the sides.
309   // theBorderFirstNode is merged with theSide2FirstNode.
310   // if (!theSide2IsFreeBorder) then theSide2SecondNode gives
311   // the last node on the side 2, which will be merged with
312   // theBorderLastNode.
313   // if (theSide2IsFreeBorder) then theSide2SecondNode will
314   // be merged with theBorderSecondNode.
315   // if (theSide2IsFreeBorder && theSide2ThirdNode == 0) then
316   // the 2 free borders are sewn link by link and no additional
317   // nodes are inserted.
318   // Return false, if sewing failed.
319
320   Sew_Error SewSideElements (std::map<int,const SMDS_MeshElement*>& theSide1,
321                              std::map<int,const SMDS_MeshElement*>& theSide2,
322                              const SMDS_MeshNode*               theFirstNode1ToMerge,
323                              const SMDS_MeshNode*               theFirstNode2ToMerge,
324                              const SMDS_MeshNode*               theSecondNode1ToMerge,
325                              const SMDS_MeshNode*               theSecondNode2ToMerge);
326   // Sew two sides of a mesh. Nodes belonging to theSide1 are
327   // merged with nodes of elements of theSide2.
328   // Number of elements in theSide1 and in theSide2 must be
329   // equal and they should have similar node connectivity.
330   // The nodes to merge should belong to side s borders and
331   // the first node should be linked to the second.
332
333   void InsertNodesIntoLink(const SMDS_MeshElement*          theFace,
334                            const SMDS_MeshNode*             theBetweenNode1,
335                            const SMDS_MeshNode*             theBetweenNode2,
336                            std::list<const SMDS_MeshNode*>& theNodesToInsert,
337                            const bool                       toCreatePoly = false);
338   // insert theNodesToInsert into theFace between theBetweenNode1 and theBetweenNode2.
339   // If toCreatePoly is true, replace theFace by polygon, else split theFace.
340
341   void UpdateVolumes (const SMDS_MeshNode*             theBetweenNode1,
342                       const SMDS_MeshNode*             theBetweenNode2,
343                       std::list<const SMDS_MeshNode*>& theNodesToInsert);
344   // insert theNodesToInsert into all volumes, containing link
345   // theBetweenNode1 - theBetweenNode2, between theBetweenNode1 and theBetweenNode2.
346
347   void ConvertToQuadratic(const bool theForce3d);
348   //converts all mesh to quadratic one, deletes old elements, replacing 
349   //them with quadratic ones with the same id.
350
351   bool ConvertFromQuadratic();
352   //converts all mesh from quadratic to ordinary ones, deletes old quadratic elements, replacing 
353   //them with ordinary mesh elements with the same id.
354
355
356 //  static int SortQuadNodes (const SMDS_Mesh * theMesh,
357 //                            int               theNodeIds[] );
358 //  // Set 4 nodes of a quadrangle face in a good order.
359 //  // Swap 1<->2 or 2<->3 nodes and correspondingly return
360 //  // 1 or 2 else 0.
361 //
362 //  static bool SortHexaNodes (const SMDS_Mesh * theMesh,
363 //                             int               theNodeIds[] );
364 //  // Set 8 nodes of a hexahedron in a good order.
365 //  // Return success status
366
367   static void AddToSameGroups (const SMDS_MeshElement* elemToAdd,
368                                const SMDS_MeshElement* elemInGroups,
369                                SMESHDS_Mesh *          aMesh);
370   // Add elemToAdd to the groups the elemInGroups belongs to
371
372   static void RemoveElemFromGroups (const SMDS_MeshElement* removeelem,
373                                     SMESHDS_Mesh *          aMesh);
374   // remove elemToAdd from the groups 
375
376   static const SMDS_MeshElement*
377     FindFaceInSet(const SMDS_MeshNode*                     n1,
378                   const SMDS_MeshNode*                     n2,
379                   const std::map<int,const SMDS_MeshElement*>& elemSet,
380                   const std::map<int,const SMDS_MeshElement*>& avoidSet);
381   // Return a face having linked nodes n1 and n2 and which is
382   // - not in avoidSet,
383   // - in elemSet provided that !elemSet.empty()
384
385   /*!
386    * \brief Returns true if given node is medium
387     * \param n - node to check
388     * \param typeToCheck - type of elements containing the node to ask about node status
389     * \retval bool - check result
390    */
391   static bool IsMedium(const SMDS_MeshNode*      node,
392                        const SMDSAbs_ElementType typeToCheck = SMDSAbs_All);
393
394   int FindShape (const SMDS_MeshElement * theElem);
395   // Return an index of the shape theElem is on
396   // or zero if a shape not found
397
398   SMESH_Mesh * GetMesh() { return myMesh; }
399
400   SMESHDS_Mesh * GetMeshDS() { return myMesh->GetMeshDS(); }
401
402   SMESH_SequenceOfElemPtr GetLastCreatedNodes() { return myLastCreatedNodes; }
403
404   SMESH_SequenceOfElemPtr GetLastCreatedElems() { return myLastCreatedElems; }
405
406 private:
407
408   void ConvertElemToQuadratic(SMESHDS_SubMesh *theSm,
409                               SMESH_MesherHelper* theHelper,
410                               const bool theForce3d);
411   //Auxiliary function for "ConvertToQuadratic" is intended to convert
412   //elements contained in submesh to quadratic
413
414   void RemoveQuadElem( SMESHDS_SubMesh *theSm,
415                        SMDS_ElemIteratorPtr theItr,
416                        RemoveQuadNodeMap& theRemoveNodeMap);
417   //Auxiliary function for "ConvertFromQuadratic" is intended to convert quadratic
418   //element to ordinary and for removing quadratic nodes
419
420 private:
421
422   SMESH_Mesh * myMesh;
423
424   /*!
425    * Sequence for keeping nodes created during last operation
426    */
427   SMESH_SequenceOfElemPtr myLastCreatedNodes;
428
429   /*!
430    * Sequence for keeping elements created during last operation
431    */
432   SMESH_SequenceOfElemPtr myLastCreatedElems;
433
434 };
435
436 #endif