SALOME - SMESH
SMESH_Block.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_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
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Friends Defines