SALOME - SMESH
|
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