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