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_Block.hxx 00023 // Created : Tue Nov 30 12:42:18 2004 00024 // Author : Edward AGAPOV (eap) 00025 // 00026 #ifndef SMESH_Block_HeaderFile 00027 #define SMESH_Block_HeaderFile 00028 00029 #include "SMESH_SMESH.hxx" 00030 00031 //#include <Geom2d_Curve.hxx> 00032 //#include <Geom_Curve.hxx> 00033 //#include <Geom_Surface.hxx> 00034 00035 #include <TopExp.hxx> 00036 #include <TopTools_IndexedMapOfOrientedShape.hxx> 00037 #include <TopoDS_Edge.hxx> 00038 #include <TopoDS_Face.hxx> 00039 #include <TopoDS_Shell.hxx> 00040 #include <TopoDS_Vertex.hxx> 00041 #include <gp_XY.hxx> 00042 #include <gp_XYZ.hxx> 00043 #include <math_FunctionSetWithDerivatives.hxx> 00044 00045 #include <ostream> 00046 #include <vector> 00047 #include <list> 00048 00049 class SMDS_MeshVolume; 00050 class SMDS_MeshNode; 00051 class Adaptor3d_Surface; 00052 class Adaptor2d_Curve2d; 00053 class Adaptor3d_Curve; 00054 class gp_Pnt; 00055 00056 // ========================================================= 00057 // class calculating coordinates of 3D points by normalized 00058 // parameters inside the block and vice versa 00059 // ========================================================= 00060 00061 class SMESH_EXPORT SMESH_Block: public math_FunctionSetWithDerivatives 00062 { 00063 public: 00064 enum TShapeID { 00065 // ---------------------------- 00066 // Ids of the block sub-shapes 00067 // ---------------------------- 00068 ID_NONE = 0, 00069 00070 ID_V000 = 1, ID_V100, ID_V010, ID_V110, ID_V001, ID_V101, ID_V011, ID_V111, 00071 00072 ID_Ex00, ID_Ex10, ID_Ex01, ID_Ex11, 00073 ID_E0y0, ID_E1y0, ID_E0y1, ID_E1y1, 00074 ID_E00z, ID_E10z, ID_E01z, ID_E11z, 00075 00076 ID_Fxy0, ID_Fxy1, ID_Fx0z, ID_Fx1z, ID_F0yz, ID_F1yz, 00077 00078 ID_Shell 00079 }; 00080 enum { // to use TShapeID for indexing certain type subshapes 00081 00082 ID_FirstV = ID_V000, ID_FirstE = ID_Ex00, ID_FirstF = ID_Fxy0 00083 00084 }; 00085 00086 00087 public: 00088 // ------------------------------------------------- 00089 // Block topology in terms of block sub-shapes' ids 00090 // ------------------------------------------------- 00091 00092 static int NbVertices() { return 8; } 00093 static int NbEdges() { return 12; } 00094 static int NbFaces() { return 6; } 00095 static int NbSubShapes() { return ID_Shell; } 00096 // to avoid magic numbers when allocating memory for subshapes 00097 00098 static inline bool IsVertexID( int theShapeID ) 00099 { return ( theShapeID >= ID_V000 && theShapeID <= ID_V111 ); } 00100 00101 static inline bool IsEdgeID( int theShapeID ) 00102 { return ( theShapeID >= ID_Ex00 && theShapeID <= ID_E11z ); } 00103 00104 static inline bool IsFaceID( int theShapeID ) 00105 { return ( theShapeID >= ID_Fxy0 && theShapeID <= ID_F1yz ); } 00106 00107 static int ShapeIndex( int theShapeID ) 00108 { 00109 if ( IsVertexID( theShapeID )) return theShapeID - ID_V000; 00110 if ( IsEdgeID( theShapeID )) return theShapeID - ID_Ex00; 00111 if ( IsFaceID( theShapeID )) return theShapeID - ID_Fxy0; 00112 return 0; 00113 } 00114 // return index [0-...] for each type of sub-shapes, 00115 // for example : 00116 // ShapeIndex( ID_Ex00 ) == 0 00117 // ShapeIndex( ID_Ex10 ) == 1 00118 00119 static void GetFaceEdgesIDs (const int faceID, std::vector< int >& edgeVec ); 00120 // return edges IDs of a face in the order u0, u1, 0v, 1v 00121 00122 static void GetEdgeVertexIDs (const int edgeID, std::vector< int >& vertexVec ); 00123 // return vertex IDs of an edge 00124 00125 static int GetCoordIndOnEdge (const int theEdgeID) 00126 { return (theEdgeID < ID_E0y0) ? 1 : (theEdgeID < ID_E00z) ? 2 : 3; } 00127 // return an index of a coordinate which varies along the edge 00128 00129 static double* GetShapeCoef (const int theShapeID); 00130 // for theShapeID( TShapeID ), returns 3 coefficients used 00131 // to compute an addition of an on-theShape point to coordinates 00132 // of an in-shell point. If an in-shell point has parameters (Px,Py,Pz), 00133 // then the addition of a point P is computed as P*kx*ky*kz and ki is 00134 // defined by the returned coef like this: 00135 // ki = (coef[i] == 0) ? 1 : (coef[i] < 0) ? 1 - Pi : Pi 00136 00137 static int GetShapeIDByParams ( const gp_XYZ& theParams ); 00138 // define an id of the block sub-shape by point parameters 00139 00140 static std::ostream& DumpShapeID (const int theBlockShapeID, std::ostream& stream); 00141 // DEBUG: dump an id of a block sub-shape 00142 00143 00144 public: 00145 // --------------- 00146 // Initialization 00147 // --------------- 00148 00149 SMESH_Block(); 00150 00151 bool LoadBlockShapes(const TopoDS_Shell& theShell, 00152 const TopoDS_Vertex& theVertex000, 00153 const TopoDS_Vertex& theVertex001, 00154 TopTools_IndexedMapOfOrientedShape& theShapeIDMap ); 00155 // Initialize block geometry with theShell, 00156 // add sub-shapes of theBlock to theShapeIDMap so that they get 00157 // IDs acoording to enum TShapeID 00158 00159 bool LoadBlockShapes(const TopTools_IndexedMapOfOrientedShape& theShapeIDMap); 00160 // Initialize block geometry with shapes from theShapeIDMap 00161 00162 bool LoadMeshBlock(const SMDS_MeshVolume* theVolume, 00163 const int theNode000Index, 00164 const int theNode001Index, 00165 std::vector<const SMDS_MeshNode*>& theOrderedNodes); 00166 // prepare to work with theVolume and 00167 // return nodes in theVolume corners in the order of TShapeID enum 00168 00169 bool LoadFace(const TopoDS_Face& theFace, 00170 const int theFaceID, 00171 const TopTools_IndexedMapOfOrientedShape& theShapeIDMap); 00172 // Load face geometry. 00173 // It is enough to compute params or coordinates on the face. 00174 // Face subshapes must be loaded into theShapeIDMap before 00175 00176 static bool Insert(const TopoDS_Shape& theShape, 00177 const int theShapeID, 00178 TopTools_IndexedMapOfOrientedShape& theShapeIDMap); 00179 // Insert theShape into theShapeIDMap with theShapeID, 00180 // Not yet set shapes preceding theShapeID are filled with compounds 00181 // Return true if theShape was successfully bound to theShapeID 00182 00183 static bool FindBlockShapes(const TopoDS_Shell& theShell, 00184 const TopoDS_Vertex& theVertex000, 00185 const TopoDS_Vertex& theVertex001, 00186 TopTools_IndexedMapOfOrientedShape& theShapeIDMap ); 00187 // add sub-shapes of theBlock to theShapeIDMap so that they get 00188 // IDs acoording to enum TShapeID 00189 00190 public: 00191 // --------------------------------- 00192 // Define coordinates by parameters 00193 // --------------------------------- 00194 00195 bool VertexPoint( const int theVertexID, gp_XYZ& thePoint ) const { 00196 if ( !IsVertexID( theVertexID )) return false; 00197 thePoint = myPnt[ theVertexID - ID_FirstV ]; return true; 00198 } 00199 // return vertex coordinates, parameters are defined by theVertexID 00200 00201 bool EdgePoint( const int theEdgeID, const gp_XYZ& theParams, gp_XYZ& thePoint ) const { 00202 if ( !IsEdgeID( theEdgeID )) return false; 00203 thePoint = myEdge[ theEdgeID - ID_FirstE ].Point( theParams ); return true; 00204 } 00205 // return coordinates of a point on edge 00206 00207 bool EdgeU( const int theEdgeID, const gp_XYZ& theParams, double& theU ) const { 00208 if ( !IsEdgeID( theEdgeID )) return false; 00209 theU = myEdge[ theEdgeID - ID_FirstE ].GetU( theParams ); return true; 00210 } 00211 // return parameter on edge by in-block parameters 00212 00213 bool FacePoint( const int theFaceID, const gp_XYZ& theParams, gp_XYZ& thePoint ) const { 00214 if ( !IsFaceID ( theFaceID )) return false; 00215 thePoint = myFace[ theFaceID - ID_FirstF ].Point( theParams ); return true; 00216 } 00217 // return coordinates of a point on face 00218 00219 bool FaceUV( const int theFaceID, const gp_XYZ& theParams, gp_XY& theUV ) const { 00220 if ( !IsFaceID ( theFaceID )) return false; 00221 theUV = myFace[ theFaceID - ID_FirstF ].GetUV( theParams ); return true; 00222 } 00223 // return UV coordinates on a face by in-block parameters 00224 00225 bool ShellPoint( const gp_XYZ& theParams, gp_XYZ& thePoint ) const; 00226 // return coordinates of a point in shell 00227 00228 static bool ShellPoint(const gp_XYZ& theParams, 00229 const std::vector<gp_XYZ>& thePointOnShape, 00230 gp_XYZ& thePoint ); 00231 // computes coordinates of a point in shell by points on sub-shapes 00232 // and point parameters. 00233 // thePointOnShape[ subShapeID ] must be a point on a subShape; 00234 // thePointOnShape.size() == ID_Shell, thePointOnShape[0] not used 00235 00236 00237 public: 00238 // --------------------------------- 00239 // Define parameters by coordinates 00240 // --------------------------------- 00241 00242 bool ComputeParameters (const gp_Pnt& thePoint, 00243 gp_XYZ& theParams, 00244 const int theShapeID = ID_Shell, 00245 const gp_XYZ& theParamsHint = gp_XYZ(-1,-1,-1)); 00246 // compute point parameters in the block. 00247 // Note: for edges, it is better to use EdgeParameters() 00248 00249 bool VertexParameters(const int theVertexID, gp_XYZ& theParams); 00250 // return parameters of a vertex given by TShapeID 00251 00252 bool EdgeParameters(const int theEdgeID, const double theU, gp_XYZ& theParams); 00253 // return parameters of a point given by theU on edge 00254 00255 00256 public: 00257 // --------------- 00258 // Block geomerty 00259 // --------------- 00260 00261 00262 00263 public: 00264 // --------- 00265 // Services 00266 // --------- 00267 00268 static bool IsForwardEdge (const TopoDS_Edge & theEdge, 00269 const TopTools_IndexedMapOfOrientedShape& theShapeIDMap) { 00270 int v1ID = theShapeIDMap.FindIndex( TopExp::FirstVertex( theEdge ).Oriented( TopAbs_FORWARD )); 00271 int v2ID = theShapeIDMap.FindIndex( TopExp::LastVertex( theEdge ).Oriented( TopAbs_FORWARD )); 00272 return ( v1ID < v2ID ); 00273 } 00274 // Return true if an in-block parameter increases along theEdge curve 00275 00276 static int GetOrderedEdges (const TopoDS_Face& theFace, 00277 TopoDS_Vertex theFirstVertex, 00278 std::list< TopoDS_Edge >& theEdges, 00279 std::list< int > & theNbVertexInWires, 00280 const bool theShapeAnalysisAlgo=false); 00281 // Return nb wires and a list of oredered edges. 00282 // It is used to assign indices to subshapes. 00283 // theFirstVertex may be NULL. 00284 // Always try to set a seam edge first 00285 // if (theShapeAnalysisAlgo) then ShapeAnalysis::OuterWire() is used to find the outer 00286 // wire else BRepTools::OuterWire() is used 00287 00288 public: 00289 // ----------------------------------------------------------- 00290 // Methods of math_FunctionSetWithDerivatives used internally 00291 // to define parameters by coordinates 00292 // ----------------------------------------------------------- 00293 Standard_Integer NbVariables() const; 00294 Standard_Integer NbEquations() const; 00295 Standard_Boolean Value(const math_Vector& X,math_Vector& F) ; 00296 Standard_Boolean Derivatives(const math_Vector& X,math_Matrix& D) ; 00297 Standard_Boolean Values(const math_Vector& X,math_Vector& F,math_Matrix& D) ; 00298 Standard_Integer GetStateNumber (); 00299 00300 protected: 00301 00305 void init(); 00306 00307 // Note: to compute params of a point on a face, it is enough to set 00308 // TFace, TEdge's and points for that face only 00309 00310 // Note 2: curve adaptors need to have only Value(double), FirstParameter() and 00311 // LastParameter() defined to be used by Block algoritms 00312 00313 class SMESH_EXPORT TEdge { 00314 int myCoordInd; 00315 double myFirst; 00316 double myLast; 00317 Adaptor3d_Curve* myC3d; 00318 // if mesh volume 00319 gp_XYZ myNodes[2]; 00320 public: 00321 void Set( const int edgeID, Adaptor3d_Curve* curve, const bool isForward ); 00322 void Set( const int edgeID, const gp_XYZ& node1, const gp_XYZ& node2 ); 00323 Adaptor3d_Curve* GetCurve() const { return myC3d; } 00324 double EndParam(int i) const { return i ? myLast : myFirst; } 00325 int CoordInd() const { return myCoordInd; } 00326 const gp_XYZ& NodeXYZ(int i) const { return i ? myNodes[1] : myNodes[0]; } 00327 gp_XYZ Point( const gp_XYZ& theParams ) const; // Return coord by params 00328 double GetU( const gp_XYZ& theParams ) const; // Return U by params 00329 TEdge(): myC3d(0) {} 00330 ~TEdge(); 00331 }; 00332 00333 class SMESH_EXPORT TFace { 00334 // 4 edges in the order u0, u1, 0v, 1v 00335 int myCoordInd[ 4 ]; 00336 double myFirst [ 4 ]; 00337 double myLast [ 4 ]; 00338 Adaptor2d_Curve2d* myC2d [ 4 ]; 00339 // 4 corner points in the order 00, 10, 11, 01 00340 gp_XY myCorner [ 4 ]; 00341 // surface 00342 Adaptor3d_Surface* myS; 00343 // if mesh volume 00344 gp_XYZ myNodes[4]; 00345 public: 00346 void Set( const int faceID, Adaptor3d_Surface* S, // must be in GetFaceEdgesIDs() order: 00347 Adaptor2d_Curve2d* c2d[4], const bool isForward[4] ); 00348 void Set( const int faceID, const TEdge& edgeU0, const TEdge& edgeU1 ); 00349 gp_XY GetUV( const gp_XYZ& theParams ) const; 00350 gp_XYZ Point( const gp_XYZ& theParams ) const; 00351 int GetUInd() const { return myCoordInd[ 0 ]; } 00352 int GetVInd() const { return myCoordInd[ 2 ]; } 00353 void GetCoefs( int i, const gp_XYZ& theParams, double& eCoef, double& vCoef ) const; 00354 TFace(): myS(0) { myC2d[0]=myC2d[1]=myC2d[2]=myC2d[3]=0; } 00355 ~TFace(); 00356 }; 00357 00358 // geometry in the order as in TShapeID: 00359 // 8 vertices 00360 gp_XYZ myPnt[ 8 ]; 00361 // 12 edges 00362 TEdge myEdge[ 12 ]; 00363 // 6 faces 00364 TFace myFace[ 6 ]; 00365 00366 // for param computation 00367 00368 enum { SQUARE_DIST = 0, DRV_1, DRV_2, DRV_3 }; 00369 double distance () const { return sqrt( myValues[ SQUARE_DIST ]); } 00370 double funcValue(double sqDist) const { return mySquareFunc ? sqDist : sqrt(sqDist); } 00371 bool computeParameters(const gp_Pnt& thePoint, gp_XYZ& theParams, const gp_XYZ& theParamsHint); 00372 00373 int myFaceIndex; 00374 double myFaceParam; 00375 int myNbIterations; 00376 double mySumDist; 00377 double myTolerance; 00378 bool mySquareFunc; 00379 00380 gp_XYZ myPoint; // the given point 00381 gp_XYZ myParam; // the best parameters guess 00382 double myValues[ 4 ]; // values computed at myParam: square distance and 3 derivatives 00383 00384 typedef std::pair<gp_XYZ,gp_XYZ> TxyzPair; 00385 TxyzPair my3x3x3GridNodes[ 27 ]; // to compute the first param guess 00386 bool myGridComputed; 00387 }; 00388 00389 00390 #endif