Salome HOME
f641ba64c5ead2510cc896a6cd4ba92530d62104
[modules/smesh.git] / src / SMESH / SMESH_Block.hxx
1 //  Copyright (C) 2003  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
2 //  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS 
3 // 
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. 
8 // 
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. 
13 // 
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 
17 // 
18 //  See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org 
19
20 // File      : SMESH_Block.hxx
21 // Created   : Tue Nov 30 12:42:18 2004
22 // Author    : Edward AGAPOV (eap)
23
24
25 #ifndef SMESH_Block_HeaderFile
26 #define SMESH_Block_HeaderFile
27
28 #include "SMESH_SMESH.hxx"
29
30 #include <Geom2d_Curve.hxx>
31 #include <Geom_Curve.hxx>
32 #include <Geom_Surface.hxx>
33 #include <TopExp.hxx>
34 #include <TopTools_IndexedMapOfOrientedShape.hxx>
35 #include <TopoDS_Edge.hxx>
36 #include <TopoDS_Shell.hxx>
37 #include <TopoDS_Vertex.hxx>
38 #include <gp_Pnt.hxx>
39 #include <gp_Trsf.hxx>
40 #include <gp_XY.hxx>
41 #include <gp_XYZ.hxx>
42 #include <math_FunctionSetWithDerivatives.hxx>
43 #include <math_Matrix.hxx>
44 #include <math_Vector.hxx>
45
46 #include <ostream>
47 #include <vector>
48
49 class SMDS_MeshVolume;
50 class SMDS_MeshNode;
51
52 // =========================================================
53 // class calculating coordinates of 3D points by normalized
54 // parameters inside the block and vice versa
55 // =========================================================
56
57 class SMESH_EXPORT SMESH_Block: public math_FunctionSetWithDerivatives
58 {
59  public:
60   enum TShapeID { // ids of the block sub-shapes
61     ID_NONE = 0,
62
63     ID_V000 = 1, ID_V100, ID_V010, ID_V110, ID_V001, ID_V101, ID_V011, ID_V111,
64
65     ID_Ex00, ID_Ex10, ID_Ex01, ID_Ex11,
66     ID_E0y0, ID_E1y0, ID_E0y1, ID_E1y1,
67     ID_E00z, ID_E10z, ID_E01z, ID_E11z,
68
69     ID_Fxy0, ID_Fxy1, ID_Fx0z, ID_Fx1z, ID_F0yz, ID_F1yz,
70
71     ID_Shell
72     };
73
74
75  public: // methods about ids of the block sub-shapes
76
77   static int NbVertices()  { return  8; }
78   static int NbEdges()     { return 12; }
79   static int NbFaces()     { return  6; }
80   static int NbSubShapes() { return ID_Shell; }
81   // to avoid magic numbers when allocating memory for subshapes
82
83   static inline bool IsVertexID( int theShapeID )
84   { return ( theShapeID >= ID_V000 && theShapeID <= ID_V111 ); }
85
86   static inline bool IsEdgeID( int theShapeID )
87   { return ( theShapeID >= ID_Ex00 && theShapeID <= ID_E11z ); }
88
89   static inline bool IsFaceID( int theShapeID )
90   { return ( theShapeID >= ID_Fxy0 && theShapeID <= ID_F1yz ); }
91
92   static int ShapeIndex( int theShapeID )
93   {
94     if ( IsVertexID( theShapeID )) return theShapeID - ID_V000;
95     if ( IsEdgeID( theShapeID ))   return theShapeID - ID_Ex00;
96     if ( IsFaceID( theShapeID ))   return theShapeID - ID_Fxy0;
97     return 0;
98   }
99   // return index [0-...] for each type of sub-shapes,
100   // for example :
101   // ShapeIndex( ID_Ex00 ) == 0
102   // ShapeIndex( ID_Ex10 ) == 1
103
104   static void GetFaceEdgesIDs (const int faceID, vector< int >& edgeVec );
105   // return edges IDs of a face in the order u0, u1, 0v, 1v
106
107   static void GetEdgeVertexIDs (const int edgeID, vector< int >& vertexVec );
108   // return vertex IDs of an edge
109
110   static int GetCoordIndOnEdge (const int theEdgeID)
111   { return (theEdgeID < ID_E0y0) ? 1 : (theEdgeID < ID_E00z) ? 2 : 3; }
112   // return an index of a coordinate which varies along the edge
113
114   static double* GetShapeCoef (const int theShapeID);
115   // for theShapeID( TShapeID ), returns 3 coefficients used
116   // to compute an addition of an on-theShape point to coordinates
117   // of an in-shell point. If an in-shell point has parameters (Px,Py,Pz),
118   // then the addition of a point P is computed as P*kx*ky*kz and ki is
119   // defined by the returned coef like this:
120   // ki = (coef[i] == 0) ? 1 : (coef[i] < 0) ? 1 - Pi : Pi
121
122   static int GetShapeIDByParams ( const gp_XYZ& theParams );
123   // define an id of the block sub-shape by point parameters
124
125   static ostream& DumpShapeID (const int theBlockShapeID, ostream& stream);
126   // DEBUG: dump an id of a block sub-shape
127
128
129  public: // initialization
130
131   SMESH_Block (): myNbIterations(0), mySumDist(0.) {}
132
133   bool LoadBlockShapes(const TopoDS_Shell&         theShell,
134                        const TopoDS_Vertex&        theVertex000,
135                        const TopoDS_Vertex&        theVertex001,
136                        TopTools_IndexedMapOfOrientedShape& theShapeIDMap );
137   // add sub-shapes of theBlock to theShapeIDMap so that they get
138   // IDs acoording to enum TShapeID
139
140   bool LoadMeshBlock(const SMDS_MeshVolume*        theVolume,
141                      const int                     theNode000Index,
142                      const int                     theNode001Index,
143                      vector<const SMDS_MeshNode*>& theOrderedNodes);
144   // prepare to work with theVolume and
145   // return nodes in the order of TShapeID enum
146
147
148  public: // define coordinates by parameters
149
150   bool VertexPoint( const int theVertexID, gp_XYZ& thePoint ) const {
151     if ( !IsVertexID( theVertexID ))           return false;
152     thePoint = myPnt[ theVertexID - ID_V000 ]; return true;
153   }
154   // return vertex coordinates, parameters are defined by theVertexID
155
156   bool EdgePoint( const int theEdgeID, const gp_XYZ& theParams, gp_XYZ& thePoint ) const {
157     if ( !IsEdgeID( theEdgeID ))                                 return false;
158     thePoint = myEdge[ theEdgeID - ID_Ex00 ].Point( theParams ); return true;
159   }
160   // return coordinates of a point on edge
161
162   bool FacePoint( const int theFaceID, const gp_XYZ& theParams, gp_XYZ& thePoint ) const {
163     if ( !IsFaceID ( theFaceID ))                                return false;
164     thePoint = myFace[ theFaceID - ID_Fxy0 ].Point( theParams ); return true;
165   }
166   // return coordinates of a point on face
167
168   bool ShellPoint( const gp_XYZ& theParams, gp_XYZ& thePoint ) const;
169   // return coordinates of a point in shell
170
171   static bool ShellPoint(const gp_XYZ&         theParams,
172                          const vector<gp_XYZ>& thePointOnShape,
173                          gp_XYZ&               thePoint );
174   // computes coordinates of a point in shell by points on sub-shapes;
175   // thePointOnShape[ subShapeID ] must be a point on a subShape;
176   // thePointOnShape.size() == ID_Shell, thePointOnShape[0] not used
177
178
179  public: // define parameters by coordinates
180
181   bool ComputeParameters (const gp_Pnt& thePoint,
182                           gp_XYZ&       theParams,
183                           const int     theShapeID = ID_Shell);
184   // compute point parameters in the block.
185   // Note: for edges, it is better to use EdgeParameters()
186
187   bool VertexParameters(const int theVertexID, gp_XYZ& theParams);
188   // return parameters of a vertex given by TShapeID
189
190   bool EdgeParameters(const int theEdgeID, const double theU, gp_XYZ& theParams);
191   // return parameters of a point given by theU on edge
192
193
194  public: // services
195
196   static bool IsForwardEdge (const TopoDS_Edge &                 theEdge,
197                              TopTools_IndexedMapOfOrientedShape& theShapeIDMap) {
198     int v1ID = theShapeIDMap.FindIndex( TopExp::FirstVertex( theEdge ).Oriented( TopAbs_FORWARD ));
199     int v2ID = theShapeIDMap.FindIndex( TopExp::LastVertex( theEdge ).Oriented( TopAbs_FORWARD ));
200     return ( v1ID < v2ID );
201   }
202   // Return true if an in-block parameter increases along theEdge curve
203
204   static void Swap(double& a, double& b) { double tmp = a; a = b; b = tmp; }
205
206
207  public:
208   // methods of math_FunctionSetWithDerivatives used internally
209   // to define parameters by coordinates
210   Standard_Integer NbVariables() const;
211   Standard_Integer NbEquations() const;
212   Standard_Boolean Value(const math_Vector& X,math_Vector& F) ;
213   Standard_Boolean Derivatives(const math_Vector& X,math_Matrix& D) ;
214   Standard_Boolean Values(const math_Vector& X,math_Vector& F,math_Matrix& D) ;
215   Standard_Integer GetStateNumber ();
216
217  private:
218
219   struct TEdge {
220     int                myCoordInd;
221     double             myFirst;
222     double             myLast;
223     Handle(Geom_Curve) myC3d;
224     gp_Trsf            myTrsf;
225     double GetU( const gp_XYZ& theParams ) const;
226     gp_XYZ Point( const gp_XYZ& theParams ) const;
227     // if mesh volume
228     gp_XYZ             myNodes[2];
229   };
230
231   struct TFace {
232     // 4 edges in the order u0, u1, 0v, 1v
233     int                  myCoordInd[ 4 ];
234     double               myFirst   [ 4 ];
235     double               myLast    [ 4 ];
236     Handle(Geom2d_Curve) myC2d     [ 4 ];
237     // 4 corner points in the order 00, 10, 11, 01
238     gp_XY                myCorner  [ 4 ];
239     // surface
240     Handle(Geom_Surface) myS;
241     gp_Trsf              myTrsf;
242     gp_XY  GetUV( const gp_XYZ& theParams ) const;
243     gp_XYZ Point( const gp_XYZ& theParams ) const;
244     int GetUInd() const { return myCoordInd[ 0 ]; }
245     int GetVInd() const { return myCoordInd[ 2 ]; }
246     void GetCoefs( int i, const gp_XYZ& theParams, double& eCoef, double& vCoef ) const;
247     // if mesh volume
248     gp_XYZ               myNodes[4];
249   };
250
251   TopoDS_Shell myShell;
252   // geometry in the order as in TShapeID:
253   // 8 vertices
254   gp_XYZ myPnt[ 8 ];
255   // 12 edges
256   TEdge  myEdge[ 12 ];
257   // 6 faces
258   TFace  myFace[ 6 ];
259
260   // for param computation
261
262   int      myFaceIndex;
263   double   myFaceParam;
264   int      myNbIterations;
265   double   mySumDist;
266
267   gp_XYZ   myPoint; // the given point
268   gp_XYZ   myParam; // the best parameters guess
269   double   myValues[ 4 ]; // values computed at myParam
270
271   typedef pair<gp_XYZ,gp_XYZ> TxyzPair;
272   TxyzPair my3x3x3GridNodes[ 27 ];
273   bool     myGridComputed;
274 };
275
276
277 #endif