Back to index

salome-smesh  6.5.0
SMESH_Pattern.hxx
Go to the documentation of this file.
00001 // Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
00002 //
00003 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
00004 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
00005 //
00006 // This library is free software; you can redistribute it and/or
00007 // modify it under the terms of the GNU Lesser General Public
00008 // License as published by the Free Software Foundation; either
00009 // version 2.1 of the License.
00010 //
00011 // This library is distributed in the hope that it will be useful,
00012 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00013 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014 // Lesser General Public License for more details.
00015 //
00016 // You should have received a copy of the GNU Lesser General Public
00017 // License along with this library; if not, write to the Free Software
00018 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
00019 //
00020 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
00021 //
00022 
00023 // File      : SMESH_Pattern.hxx
00024 // Created   : Mon Aug  2 10:30:00 2004
00025 // Author    : Edward AGAPOV (eap)
00026 //
00027 #ifndef SMESH_Pattern_HeaderFile
00028 #define SMESH_Pattern_HeaderFile
00029 
00030 #include "SMESH_SMESH.hxx"
00031 
00032 #include <vector>
00033 #include <list>
00034 #include <map>
00035 #include <set>
00036 #include <iostream>
00037 
00038 #include <TopoDS_Shape.hxx>
00039 #include <TopTools_IndexedMapOfOrientedShape.hxx>
00040 #include <gp_XYZ.hxx>
00041 #include <gp_XY.hxx>
00042 #include <gp_Pnt.hxx>
00043 
00044 class SMDS_MeshElement;
00045 class SMDS_MeshFace;
00046 class SMDS_MeshVolume;
00047 class SMDS_MeshNode;
00048 class SMESH_Mesh;
00049 class SMESHDS_SubMesh;
00050 class TopoDS_Shell;
00051 class TopoDS_Vertex;
00052 class TopoDS_Face;
00053 class TopoDS_Edge;
00054 
00055 //
00056 // Class allowing meshing by mapping of pre-defined patterns: it generates
00057 // a 2D mesh on a geometrical face or a 3D mesh inside a geometrical block
00058 // of 6 faces.
00059 //
00060 
00061 class SMESH_EXPORT SMESH_Pattern {
00062  public:
00063   
00064   SMESH_Pattern ();
00065 
00066   void Clear();
00067   // clear fields
00068 
00069   bool Load (const char* theFileContents);
00070   // Load a pattern from <theFileContents>
00071 
00072   bool Load (SMESH_Mesh*        theMesh,
00073              const TopoDS_Face& theFace,
00074              bool               theProject = false);
00075   // Create a pattern from the mesh built on <theFace>.
00076   // <theProject>==true makes override nodes positions
00077   // on <theFace> computed by mesher
00078 
00079   bool Load (SMESH_Mesh*         theMesh,
00080              const TopoDS_Shell& theBlock);
00081   // Create a pattern from the mesh built on <theBlock>
00082 
00083   bool Save (std::ostream& theFile);
00084   // Save the loaded pattern into theFile
00085 
00086   bool Apply (const TopoDS_Face&   theFace,
00087               const TopoDS_Vertex& theVertexOnKeyPoint1,
00088               const bool           theReverse);
00089   // Compute nodes coordinates applying
00090   // the loaded pattern to <theFace>. The first key-point
00091   // will be mapped into <theVertexOnKeyPoint1>, which must
00092   // be in the outer wire of theFace
00093 
00094   bool Apply (const TopoDS_Shell&  theBlock,
00095               const TopoDS_Vertex& theVertex000,
00096               const TopoDS_Vertex& theVertex001);
00097   // Compute nodes coordinates applying
00098   // the loaded pattern to <theBlock>. The (0,0,0) key-point
00099   // will be mapped into <theVertex000>. The
00100   // (0,0,1) key-point will be mapped into <theVertex001>.
00101 
00102   bool Apply (const SMDS_MeshFace* theFace,
00103               const int            theNodeIndexOnKeyPoint1,
00104               const bool           theReverse);
00105   // Compute nodes coordinates applying
00106   // the loaded pattern to <theFace>. The first key-point
00107   // will be mapped into <theNodeIndexOnKeyPoint1>-th node
00108 
00109   bool Apply (SMESH_Mesh*          theMesh,
00110               const SMDS_MeshFace* theFace,
00111               const TopoDS_Shape&  theSurface,
00112               const int            theNodeIndexOnKeyPoint1,
00113               const bool           theReverse);
00114   // Compute nodes coordinates applying
00115   // the loaded pattern to <theFace>. The first key-point
00116   // will be mapped into <theNodeIndexOnKeyPoint1>-th node
00117 
00118   bool Apply (SMESH_Mesh*                     theMesh,
00119               std::set<const SMDS_MeshFace*>& theFaces,
00120               const int                       theNodeIndexOnKeyPoint1,
00121               const bool                      theReverse);
00122   // Compute nodes coordinates applying
00123   // the loaded pattern to <theFaces>. The first key-point
00124   // will be mapped into <theNodeIndexOnKeyPoint1>-th node
00125 
00126   bool Apply (const SMDS_MeshVolume* theVolume,
00127               const int              theNode000Index,
00128               const int              theNode001Index);
00129   // Compute nodes coordinates applying
00130   // the loaded pattern to <theVolume>. The (0,0,0) key-point
00131   // will be mapped into <theNode000Index>-th node. The
00132   // (0,0,1) key-point will be mapped into <theNode000Index>-th
00133   // node.
00134 
00135   bool Apply (std::set<const SMDS_MeshVolume*>& theVolumes,
00136               const int                         theNode000Index,
00137               const int                         theNode001Index);
00138   // Compute nodes coordinates applying
00139   // the loaded pattern to <theVolumes>. The (0,0,0) key-point
00140   // will be mapped into <theNode000Index>-th node. The
00141   // (0,0,1) key-point will be mapped into <theNode000Index>-th
00142   // node.
00143 
00144   bool GetMappedPoints ( std::list<const gp_XYZ *> & thePoints ) const;
00145   // Return nodes coordinates computed by Apply() method
00146 
00147   bool MakeMesh(SMESH_Mesh* theMesh,
00148                 const bool toCreatePolygons = false,
00149                 const bool toCreatePolyedrs = false);
00150   // Create nodes and elements in <theMesh> using nodes
00151   // coordinates computed by either of Apply...() methods
00152 
00153   // ----------
00154   // Inquiries
00155   // ----------
00156 
00157   enum ErrorCode {
00158     ERR_OK,
00159     // Load(file)
00160     ERR_READ_NB_POINTS, // couldn't read nb of points
00161     ERR_READ_POINT_COORDS, // invalid nb of point coordinates
00162     ERR_READ_TOO_FEW_POINTS,  // too few points in a pattern
00163     ERR_READ_3D_COORD,  // coordinate of 3D point out of [0,1] range
00164     ERR_READ_NO_KEYPOINT, // no key-points in 2D pattern
00165     ERR_READ_BAD_INDEX, // invalid point index
00166     ERR_READ_ELEM_POINTS, // invalid nb of points in element
00167     ERR_READ_NO_ELEMS, // no elements in a pattern
00168     ERR_READ_BAD_KEY_POINT, // a key-point not on a boundary
00169     // Save(file)
00170     ERR_SAVE_NOT_LOADED, // pattern was not loaded
00171     // Load(shape)
00172     ERR_LOAD_EMPTY_SUBMESH, // no elements to load
00173     // Load(face)
00174     ERR_LOADF_NARROW_FACE, // too narrow face
00175     ERR_LOADF_CLOSED_FACE, // closed face
00176     ERR_LOADF_CANT_PROJECT, // impossible to project nodes
00177     // Load(volume)
00178     ERR_LOADV_BAD_SHAPE, // volume is not a brick of 6 faces
00179     ERR_LOADV_COMPUTE_PARAMS, // cant compute point parameters
00180     // Apply(shape)
00181     ERR_APPL_NOT_COMPUTED, // mapping failed
00182     ERR_APPL_NOT_LOADED, // pattern was not loaded
00183     ERR_APPL_BAD_DIMENTION, // wrong shape dimention
00184     ERR_APPL_BAD_NB_VERTICES, // keypoints - vertices mismatch
00185     // Apply(face)
00186     ERR_APPLF_BAD_TOPOLOGY, // bad pattern topology
00187     ERR_APPLF_BAD_VERTEX, // first vertex not on an outer face boundary
00188     ERR_APPLF_INTERNAL_EEROR, // program error
00189     // Apply(volume)
00190     ERR_APPLV_BAD_SHAPE, // volume is not a brick of 6 faces
00191     // Apply(mesh_face)
00192     ERR_APPLF_BAD_FACE_GEOM, // bad face geometry
00193     // MakeMesh
00194     ERR_MAKEM_NOT_COMPUTED, // mapping failed
00195     //Unexpected error 
00196     ERR_UNEXPECTED // Unexpected of the pattern mapping alorithm
00197   };
00198 
00199   ErrorCode GetErrorCode() const { return myErrorCode; }
00200   // return ErrorCode of the last operation
00201 
00202   bool IsLoaded() const { return !myPoints.empty() && !myElemPointIDs.empty(); }
00203   // Return true if a pattern was successfully loaded
00204 
00205   bool Is2D() const { return myIs2D; }
00206   // Return true if the loaded pattern is a 2D one
00207 
00208   bool GetPoints ( std::list<const gp_XYZ *> & thePoints ) const;
00209   // Return nodes coordinates of the pattern
00210 
00211   const std::list< int > & GetKeyPointIDs () const { return myKeyPointIDs; }
00212   // Return indices of key-points within the sequences returned by
00213   // GetPoints() and GetMappedPoints()
00214   
00215   const std::list< std::list< int > >& GetElementPointIDs (bool applied) const
00216   { return myElemXYZIDs.empty() || !applied ? myElemPointIDs : myElemXYZIDs; }
00217   // Return nodal connectivity of the elements of the pattern
00218 
00219   void DumpPoints() const;
00220   // Debug
00221 
00222   // -----------------------------
00223   // Utilities for advanced usage
00224   // -----------------------------
00225 
00226   TopoDS_Shape GetSubShape( const int i ) const {
00227     if ( i < 1 || i > myShapeIDMap.Extent() ) return TopoDS_Shape();
00228     return myShapeIDMap( i );
00229   }
00230   // Return a shape from myShapeIDMap where shapes are indexed so that first go
00231   // ordered vertices, then ordered edge, then faces and maybe a shell
00232 
00233 private:
00234   // private methods
00235 
00236   struct TPoint {
00237     gp_XYZ myInitXYZ; // loaded postion
00238     gp_XY  myInitUV;
00239     double myInitU; // [0,1]
00240     gp_Pnt myXYZ; // position to compute
00241     gp_XY  myUV;
00242     double myU;
00243     TPoint();
00244   };
00245   friend std::ostream & operator <<(std::ostream & OS, const TPoint& p);
00246 
00247   bool setErrorCode( const ErrorCode theErrorCode );
00248   // set ErrorCode and return true if it is Ok
00249 
00250   bool setShapeToMesh(const TopoDS_Shape& theShape);
00251   // Set a shape to be meshed. Return True if meshing is possible
00252 
00253   std::list< TPoint* > & getShapePoints(const TopoDS_Shape& theShape);
00254   // Return list of points located on theShape.
00255   // A list of edge-points include vertex-points (for 2D pattern only).
00256   // A list of face-points doesnt include edge-points.
00257   // A list of volume-points doesnt include face-points.
00258 
00259   std::list< TPoint* > & getShapePoints(const int theShapeID);
00260   // Return list of points located on the shape
00261 
00262   bool findBoundaryPoints();
00263   // If loaded from file, find points to map on edges and faces and
00264   // compute their parameters
00265 
00266   void arrangeBoundaries (std::list< std::list< TPoint* > >& boundaryPoints);
00267   // if there are several wires, arrange boundaryPoints so that
00268   // the outer wire goes first and fix inner wires orientation;
00269   // update myKeyPointIDs to correspond to the order of key-points
00270   // in boundaries; sort internal boundaries by the nb of key-points
00271 
00272   void computeUVOnEdge( const TopoDS_Edge& theEdge, const std::list< TPoint* > & ePoints );
00273   // compute coordinates of points on theEdge
00274 
00275   bool compUVByIsoIntersection (const std::list< std::list< TPoint* > >& boundaryPoints,
00276                                 const gp_XY&                   theInitUV,
00277                                 gp_XY&                         theUV,
00278                                 bool &                         theIsDeformed);
00279   // compute UV by intersection of iso-lines found by points on edges
00280 
00281   bool compUVByElasticIsolines(const std::list< std::list< TPoint* > >& boundaryPoints,
00282                                const std::list< TPoint* >&         pointsToCompute);
00283   // compute UV as nodes of iso-poly-lines consisting of
00284   // segments keeping relative size as in the pattern
00285 
00286   double setFirstEdge (std::list< TopoDS_Edge > & theWire, int theFirstEdgeID);
00287   // choose the best first edge of theWire; return the summary distance
00288   // between point UV computed by isolines intersection and
00289   // eventual UV got from edge p-curves
00290 
00291   typedef std::list< std::list< TopoDS_Edge > > TListOfEdgesList;
00292 
00293   bool sortSameSizeWires (TListOfEdgesList &                theWireList,
00294                           const TListOfEdgesList::iterator& theFromWire,
00295                           const TListOfEdgesList::iterator& theToWire,
00296                           const int                         theFirstEdgeID,
00297                           std::list< std::list< TPoint* > >&          theEdgesPointsList );
00298   // sort wires in theWireList from theFromWire until theToWire,
00299   // the wires are set in the order to correspond to the order
00300   // of boundaries; after sorting, edges in the wires are put
00301   // in a good order, point UVs on edges are computed and points
00302   // are appended to theEdgesPointsList
00303 
00304   typedef std::set<const SMDS_MeshNode*> TNodeSet;
00305 
00306   void mergePoints (const bool uniteGroups);
00307   // Merge XYZ on edges and/or faces.
00308 
00309   void makePolyElements(const std::vector< const SMDS_MeshNode* >& theNodes,
00310                         const bool                                 toCreatePolygons,
00311                         const bool                                 toCreatePolyedrs);
00312   // prepare intermediate data to create Polygons and Polyhedrons
00313 
00314   void createElements(SMESH_Mesh*                                 theMesh,
00315                       const std::vector<const SMDS_MeshNode* >&   theNodesVector,
00316                       const std::list< std::list< int > > &       theElemNodeIDs,
00317                       const std::vector<const SMDS_MeshElement*>& theElements);
00318   // add elements to the mesh
00319 
00320   bool getFacesDefinition(const SMDS_MeshNode**                      theBndNodes,
00321                           const int                                  theNbBndNodes,
00322                           const std::vector< const SMDS_MeshNode* >& theNodes,
00323                           std::list< int >&                          theFaceDefs,
00324                           std::vector<int>&                          theQuantity);
00325   // fill faces definition for a volume face defined by theBndNodes
00326   // return true if a face definition changes
00327   
00328 
00329   bool isReversed(const SMDS_MeshNode*    theFirstNode,
00330                   const std::list< int >& theIdsList) const;
00331   // check xyz ids order in theIdsList taking into account
00332   // theFirstNode on a link
00333 
00334   void clearMesh(SMESH_Mesh* theMesh) const;
00335   // clear mesh elements existing on myShape in theMesh
00336 
00337   static SMESHDS_SubMesh * getSubmeshWithElements(SMESH_Mesh*         theMesh,
00338                                                   const TopoDS_Shape& theShape);
00339   // return submesh containing elements bound to theShape in theMesh
00340 
00341  private:
00342   // fields
00343 
00344   typedef std::list< int > TElemDef; // element definition is its nodes ids
00345 
00346   bool                                 myIs2D;
00347   std::vector< TPoint >                myPoints;
00348   std::list< int >                     myKeyPointIDs;
00349   std::list< TElemDef >                myElemPointIDs;
00350 
00351   ErrorCode                            myErrorCode;
00352   bool                                 myIsComputed;
00353   bool                                 myIsBoundaryPointsFound;
00354 
00355   TopoDS_Shape                         myShape;
00356   // all functions assure that shapes are indexed so that first go
00357   // ordered vertices, then ordered edge, then faces and maybe a shell
00358   TopTools_IndexedMapOfOrientedShape   myShapeIDMap;
00359   std::map< int, std::list< TPoint* > >     myShapeIDToPointsMap;
00360 
00361   // for the 2d case:
00362   // nb of key-points in each of pattern boundaries
00363   std::list< int >                     myNbKeyPntInBoundary;
00364 
00365   
00366   // to compute while applying to mesh elements, not to shapes
00367 
00368   std::vector<gp_XYZ>                  myXYZ;            // XYZ of nodes to create
00369   std::list< TElemDef >                myElemXYZIDs;     // new elements definitions
00370   std::map< int, const SMDS_MeshNode*> myXYZIdToNodeMap; // map XYZ id to node of a refined element
00371   std::vector<const SMDS_MeshElement*> myElements;       // refined elements
00372   std::vector<const SMDS_MeshNode*>    myOrderedNodes;
00373 
00374    // elements to replace with polygon or polyhedron
00375   std::vector<const SMDS_MeshElement*> myPolyElems;
00376   // definitions of new poly elements
00377   std::list< TElemDef >                myPolyElemXYZIDs;
00378   std::list< std::vector<int> >        myPolyhedronQuantities;
00379 
00380   // map a boundary to XYZs on it;
00381   // a boundary (edge or face) is defined as a set of its nodes,
00382   // XYZs on a boundary are indices of myXYZ s
00383   std::map<TNodeSet,std::list<std::list<int> > >  myIdsOnBoundary;
00384   // map XYZ id to element it is in
00385   std::map< int, std::list< TElemDef* > >         myReverseConnectivity;
00386 };
00387 
00388 
00389 #endif